简体   繁体   English

Haskell:初学者函数语法混乱

[英]Haskell: beginner function syntax confusion

I'm currently trying to learn Haskell, but I'm struggling with understanding the syntax. 我目前正在尝试学习Haskell,但我正在努力理解语法。 For example, take the map function: 例如,采取map功能:

map :: (s -> t) -> [s] -> [t]
map f [] = []
map f (x:xs) = f x : map f xs

I understand what the function does, and that map has a function f :: s -> t as a parameter. 我理解该函数的作用,并且该map具有函数f :: s -> t作为参数。 But I read map :: (s -> t) -> [s] -> [t] as "map is a function which maps a function mapping from s to t to s and then to t", which is obviously wrong. 但我读map :: (s -> t) -> [s] -> [t]为“map是一个函数,它将函数映射从s映射到s再映射到s然后再映射到t”,这显然是错误的。 Could someone clear this up for me? 有人可以为我清除这个吗?

The type (s -> t) -> [s] -> [t] can be read in two ways. 类型(s -> t) -> [s] -> [t]可以通过两种方式读取。 One way is to treat it as a function of two arguments, the first a function of type s -> t and the second a list of type [s] . 一种方法是将其视为两个参数的函数,第一个是s -> t类型s -> t函数,第二个是类型[s]的列表。 The return value is of type [t] . 返回值的类型为[t]

The other way is to understand that function arrows are right-associative, so the type is equivalent to (s -> t) -> ([s] -> [t]) . 另一种方法是理解函数箭头是右关联的,因此类型等价于(s -> t) -> ([s] -> [t]) Under this interpretation, map is a function that takes a function from element to element s -> t and turns it into a function from list to list [s] -> [t] . 在这种解释下, map是一个函数,它将一个函数从元素转换为元素s -> t并将其转换为一个函数,从列表到列表[s] -> [t]

Similarly, when using the function, you can think of map foo xs as applying the function map to two arguments foo and xs . 类似地,在使用该函数时,您可以将map foo xs视为将函数map应用于两个参数fooxs Or, since function application is left -associative, you can think of it as (map foo) xs , applying map to the single argument foo to get back a new function which you then apply to xs . 或者,由于函数应用程序是关联的,您可以将其视为(map foo) xs ,将map应用于单个参数foo以获取然后应用于xs的新函数。

Since Haskell functions are curried , these are just two ways of looking at the exact same thing. 由于Haskell函数是curry ,这些只是看待完全相同的两种方式。

It might be helpful to define a couple type aliases, to make it a bit more explicit what all those arrows and brackets are doing: 定义一对类型别名可能会有所帮助,使其更加明确所有箭头和括号所做的事情:

type F1 a b = a -> b  -- type synonym for single-argument functions
type List a = [a]  -- type synonym for lists

so now you can write map 's type signature as: 所以你现在可以把map的类型签名写成:

map :: F1 s t -> List s -> List t

which, if you're more familiar with Java or C++ or whatever, looks syntactically a bit more like: 如果你对Java或C ++或其他什么更熟悉,那么在语法上看起来更像:

List<T> map(F1<S, T> fun, List<S> list); // applies fun to each element in list

So you can think of it this way: map takes a function and a list, and returns another list. 所以你可以这样想: map接受一个函数和一个列表,然后返回另一个列表。 However, since functions are curried in Haskell, you don't have to pass all parameters at once. 然而,由于功能在Haskell 咖喱 ,你不必一次通过所有参数。 You could get away with partially applying map to just its first argument. 您可以 map 部分应用于其第一个参数。 So really its type signature is more like: 所以它的类型签名更像是:

F1<List<S>, List<T>> map(F1<S, T> fun); // returns a function that applies fun to each element in a list

... which, when you call map with just that one fun argument, gives you something that sort of looks like: ...当你用一个fun参数调用map时,会给你一些类似的东西:

List<T> mapFun(List<S> list); // applies fun to each element in list

So now back to Haskell: you can read map :: (s -> t) -> [s] -> [t] either as: 现在回到Haskell:你可以读取map :: (s -> t) -> [s] -> [t]

  • " map takes a function from s to t , and a list of s , and returns a list of t " mapst获取一个函数,以及一个s列表,并返回一个t列表”
  • " map takes a function from s to t , and turns it into a function from a list of s to a list of t " mapst采用函数,并将其转换为从s 列表到t列表的函数

The former is fine; 前者很好; the latter is more helpful. 后者更有帮助。

How about "map is a function which maps a (function from s to t) over a (list of s) giving a (list of t)"? “map是一个函数,它将(从s到t的函数)映射到一个(s的列表)给出一个(t的列表)”? That is a direct translation of the type signature into English (albeit not very elegant English). 这是将类型签名直接翻译成英文(虽然不是很优雅的英文)。

Read the signature from the end: -> [t] means returns a list of t . 从最后读取签名: -> [t]表示返回t列表 The rest is 'regular' parameters. 其余的是“常规”参数。

So, map takes a function that from an s makes a t , and a list of s . 因此, map采用s生成t的函数和s的列表。

Now it's easy: take a function s->t , apply it to each element of [s] and the result of it is [t] . 现在很容易:取一个函数s->t ,将它应用于[s]每个元素,结果为[t]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM