了解Haskell类型签名 [英] Understanding Haskell Type Signatures
问题描述
Prelude> :t($)
($)::(a - > b) - > a - > b
前奏>
我应该如何解读(无双关语意思)?
一个半相似的结果也被证明令人费解:
Prelude> :t map
map ::(a - > b) - > [a] - > [b]
前奏>
我将以图
。 map
函数将操作应用于列表中的每个元素。如果我有
add3 :: Int - > Int
add3 x = x + 3
然后我可以将它应用到 Int 使用
map :
$ b
> map add3 [1,2,3,4]
[4,5,6,7]
所以,如果你看看类型签名
map ::(a - > b) - > [a] - > [b]
您会看到第一个参数是(a - > b)
,它只是一个函数,它接受 a
并返回一个 b
。第二个参数是 [a]
,它是 a
类型的值列表,返回类型 [b]
,类型为 b
的值列表。因此,在普通英语中, map
函数将一个函数应用于值列表中的每个元素,然后将这些值作为列表返回。
这就是 map
a 高阶函数的含义,它将函数作为参数并对它进行操作。查看 map
的另一种方法是在类型签名中添加一些括号以使其成为
map ::(a - > b) - > ([a] - > [b])
所以你也可以把它看作一个函数它将函数从 a
转换为 b
,转换为 [a]
到 [b]
。
($)
有类型
($)::(a - > b) - > a - > b
用于像
> add3 $ 1 + 1
5
它所做的只是向在这种情况下 1 + 1
,并将它传递给 left 上的函数,在这里 ADD3
。为什么这很重要?它有一个方便的固定性或运算符优先级,它使它等价于
> add3(1 + 1)
所以无论如何在传递给剩下。这对于将几个函数链接在一起很有用:
> add3 $ add3 $ add3 $ add3 $ 1 + 1
比$ / $更好b
> add3(add3(add3(add3(1 + 1))))
因为你没有关闭括号。
I am in the process of teaching myself Haskell and I was wondering about the following type signatures:
Prelude> :t ($)
($) :: (a -> b) -> a -> b
Prelude>
How should I interpret (no pun intended) that?
A semi-similar result is also proving to be puzzling:
Prelude> :t map
map :: (a -> b) -> [a] -> [b]
Prelude>
I'll start with map
. The map
function applies an operation to every element in a list. If I had
add3 :: Int -> Int
add3 x = x + 3
Then I could apply this to a whole list of Int
s using map
:
> map add3 [1, 2, 3, 4]
[4, 5, 6, 7]
So if you look at the type signature
map :: (a -> b) -> [a] -> [b]
You'll see that the first argument is (a -> b)
, which is just a function that takes an a
and returns a b
. The second argument is [a]
, which is a list of values of type a
, and the return type [b]
, a list of values of type b
. So in plain english, the map
function applies a function to each element in a list of values, then returns the those values as a list.
This is what makes map
a higher order function, it takes a function as an argument and does stuff with it. Another way to look at map
is to add some parentheses to the type signature to make it
map :: (a -> b) -> ([a] -> [b])
So you can also think of it as a function that transforms a function from a
to b
into a function from [a]
to [b]
.
The function ($)
has the type
($) :: (a -> b) -> a -> b
And is used like
> add3 $ 1 + 1
5
All it does is take what's to the right, in this case 1 + 1
, and passes it to the function on the left, here add3
. Why is this important? It has a handy fixity, or operator precedence, that makes it equivalent to
> add3 (1 + 1)
So whatever to the right gets essentially wrapped in parentheses before being passed to the left. This just makes it useful for chaining several functions together:
> add3 $ add3 $ add3 $ add3 $ 1 + 1
is nicer than
> add3 (add3 (add3 (add3 (1 + 1))))
because you don't have to close parentheses.
这篇关于了解Haskell类型签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!