Как правило, предпочтительнее иметь строгое или нечеткое определение типа для функции? Каковы плюсы и минусы каждого подхода? Я обнаружил, что, когда я переписал my pearson correlation code, используя строго удвоение, мне было легче писать, следовать и рассуждать (это может быть просто неопытность). Но я также вижу, как более широкое определение типа сделает функции более общеприменимыми. Можно ли охарактеризовать более строгие определения типов как форму технического долга?Ограничения типа функции
С классов типов:
import Data.List
mean :: Fractional a => [a] -> a
mean xs = s/n
where
(s , n) = foldl' k (0,0) xs
k (s, n) x = s `seq` n `seq` (s + x, n + 1)
covariance :: Fractional a => [a] -> [a] -> a
covariance xs ys = mean productXY
where
productXY = zipWith (*) [x - mx | x <- xs] [y - my | y <- ys]
mx = mean xs
my = mean ys
stddev :: Floating a => [a] -> a
stddev xs = sqrt (covariance xs xs)
pearson :: RealFloat a => [a] -> [a] -> a
pearson x y = fifthRound $ covariance x y/(stddev x * stddev y)
pearsonMatrix :: RealFloat a => [[a]] -> [[a]]
pearsonMatrix (x:xs) = [pearson x y | y <- x:xs]:(pearsonMatrix xs)
pearsonMatrix [] = []
fifthRound :: RealFrac a => a -> a
fifthRound x = (/100000) $ fromIntegral $ round (x * 100000)
с двойниками:
import Data.List
mean :: [Double] -> Double
mean xs = s/n
where
(s , n) = foldl' k (0,0) xs
k (s, n) x = s `seq` n `seq` (s + x, n + 1)
covariance :: [Double] -> [Double] -> Double
covariance xs ys = mean productXY
where
productXY = zipWith (*) [x - mx | x <- xs] [y - my | y <- ys]
mx = mean xs
my = mean ys
stddev :: [Double] -> Double
stddev xs = sqrt (covariance xs xs)
pearson :: [Double] -> [Double] -> Double
pearson x y = fifthRound (covariance x y/(stddev x * stddev y))
pearsonMatrix :: [[Double]] -> [[Double]]
pearsonMatrix (x:xs) = [pearson x y | y <- x:xs]:(pearsonMatrix xs)
pearsonMatrix [] = []
fifthRound :: Double -> Double
fifthRound x = (/100000) $ fromIntegral $ round (x * 100000)
Правильно, хотя иногда самая общая полиморфная подпись просто слишком сумасшедшая. Если список ограничений в два раза длиннее полного специализированного типа, я бы подумал об этом, действительно ли это разумно. (Хотя 'ConstraintKind'-'type'defs могут сделать такие подписи довольно читабельными, это происходит по цене безвестности в сообщениях об ошибках и т. Д.) – leftaroundabout