Hel*_*ere 3 haskell map-function
我想用来map从列表的每个元素中减去列表的平均值map。到目前为止,我得到了这个计算平均值的函数:
averageOfList :: [Float] -> Float
averageOfList [] = 0
averageOfList a = ((foldl (+) 0 a) / fromIntegral(length a))
Run Code Online (Sandbox Code Playgroud)
名单是[1.3,1.7,3.3,1.0,3.3]。我究竟如何使用平均函数map从每个元素中减去?
对于刚接触函数式编程的map人来说,这可能是他们最先纠结的概念之一。map是一个接受两个参数的函数:一个函数和一个元素列表。
的类型签名map是(a -> b) -> [a] -> [b]。该(a -> b)部分是您传递给的函数map,我们将调用它f。f接受一个值并返回另一个可能是不同类型的值。该[a]部分是您要应用f到的元素列表,我们将其称为xs。注意ftake ana的类型签名和xsis的类型签名是如何的,takes[a]的类型f必须与 中元素的类型匹配xs。另外一点需要注意的是返回类型mapIS [b]。这与 的返回类型匹配f。
这是一个使用 map 的简单示例。
plusOne :: Int -> Int
plusOne x = x + 1
xs = [1,2,3,4,5,6]
ys = map plusOne xs
Run Code Online (Sandbox Code Playgroud)
在这种情况下,a输入的类型map将是Int,输入的b类型map也将是Int。让我们看一个a和b类型不同的情况。
-- show :: a -> String
zs = map show ys
Run Code Online (Sandbox Code Playgroud)
在这种情况下a是Int和b是String。我们得到一个列表String。如果您熟悉 Python 或 C 之类的语言,您可能已经创建了一个 for 循环,它从 0 开始一直到数组长度的末尾并更改了里面的元素。这是同一个概念。
最后,要回答您的主要问题,您需要首先应用averageOfLista [Float],然后average从列表中的每个元素中减去结果。
-- show :: a -> String
zs = map show ys
Run Code Online (Sandbox Code Playgroud)
在上面的这个例子中,我写出了我们想要映射到浮点数列表的函数的名称和定义。另一种策略是在不使用名称的情况下定义一个内联函数(这称为 lambda 函数或匿名函数)。
avg = averageOfList [1.3,1.7,3.3,1.0,3.3]
subAvg x = x - avg
map subAvg [0.0,2.0,3.4,5.6]
Run Code Online (Sandbox Code Playgroud)
语法(\x -> )意味着定义一个带有一个参数的函数,我们将调用它x,然后我们为该函数定义一个主体。这是一种直接定义函数而不给它命名的方法。