了解Haskell类型签名 [英] Understanding Haskell Type Signatures

查看:132
本文介绍了了解Haskell类型签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



  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 Ints 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆