Haskell中列表理解的效率

Haskell中列表理解的效率,haskell,list-comprehension,Haskell,List Comprehension,我一直在学习Haskell和我制作了一些统计函数,可以用于Int或Float类型的列表。 以下是两个例子: mean :: (Real a, Floating b) => [a] -> b mean xs = realToFrac (sum xs) / genericLength xs sumOfSquares :: (Real a, Floating b) => [a] -> b sumOfSquares xs = [(mean xs - realToFrac x)

我一直在学习Haskell和我制作了一些统计函数,可以用于
Int
Float
类型的列表。
以下是两个例子:

mean :: (Real a, Floating b) => [a] -> b
mean xs = realToFrac (sum xs) / genericLength xs

sumOfSquares :: (Real a, Floating b) => [a] -> b
sumOfSquares xs = [(mean xs - realToFrac x) ^^ 2 | x <- xs]
或者像这样:

sumOfSquares xs = [(m - realToFrac x) ^^ 2 | x <- xs] where m = mean xs
sumOfSquares xs = [(m - realToFrac x) ^^ 2 | x <- xs, let m = mean xs]

sumOfSquares xs=[(m-realToFrac x)^^2 | x去糖化确实会产生不同的代码。您在这里考虑三种实现。我将展示它们在不理解列表的情况下的外观

-- With no let / where
sumOfSquares xs = [(mean xs - realToFrac x) ^^ 2 | x <- xs]
sumOfSquares xs = map (\x -> (mean xs - realToFrac x) ^^ 2) xs

-- With let inside the comprehension
sumOfSquares xs = [(m - realToFrac x) ^^ 2 | x <- xs, let m = mean xs]
sumOfSquares xs = map (\x -> let m = mean xs in (m - realToFrac x) ^^ 2) xs

-- With where outside the comprehension
sumOfSquares xs = [(m - realToFrac x) ^^ 2 | x <- xs] where m = mean xs
sumOfSquares xs = map (\x -> (m - realToFrac x) ^^ 2) xs where m = mean xs
并将其转换为

let y = something in \x -> f x y
只要
x
something
中不作为自由变量出现,这种优化是允许的,而且大多数编译器在这方面都相当聪明,所以您不必太担心

GHC执行了许多常见的优化,这部分是从中得到启发的。如果您想了解更多关于Haskell效率的信息,我建议您查看一下

let y = something in \x -> f x y