Haskell类型和签名

时间:2015-10-04 13:01:52

标签: haskell types functional-programming integer

我正在学习关于Haskell的考试。我不明白我如何确定一个函数的类型。功能是:

func [] f = 16
func (h : t) f = (f h) + (func t f)

我的猜测是第一行有这种类型:empty list -> a -> a其中a必须是数字类型。在Haskell表示法Num a => [] -> a -> a中,第二行有这种类型:[a]-> a -> ?它返回什么?也许(a, a)因为(f h)是一个元组。那么(func t f)a还是?我如何将两条线混合在一起?

2 个答案:

答案 0 :(得分:6)

func [] f = 16

此行定义了一个函数func,接受了一个列表和f,并返回16。该类型可以写为Num a => [b] -> c -> a

func (h : t) f = (f h) + (func t f)

此行将f类型限制为Num a => b -> a,因为:

  1. f应接受列表中的元素
  2. f ...应返回一个值,该值可以添加到func ...
  3. 的结果中

    所以,func的类型是:

    Num a => [b] -> (b -> a) -> a
    

答案 1 :(得分:3)

找出这些问题的一种(简单)方法是将其写入文件并将其加载到ghci并发出命令:t func,这在准备考试时很好但不是在此期间适用 - 所以我将引导您完成可以找到的提示。

由于@soon给出了一个非常有效的答案 - 我只会添加一些您将来可能会使用的提示:

确定参数的数量(如果函数是以无点样式编写的,这可能有点困难,即func x = const x可以写成func = const

所以在这种情况下我们得到两个参数和一个结果,所以我们可以将签名写为

func :: ? -> ? -> ?
  1. 查找结果(在本例中为16)并确定其类型 你已经注意到16是数字的东西 - 因此

    func :: Num a => ? -> ? -> a
    

    看起来是一个很好的起点。

  2. 查找可帮助您识别函数中的ADT或type / newtype的类型构造函数。

    现在在第一和第二种情况下,我们有两个提示,第一个参数是类型列表([],构造函数(:))给我们这个信息。由于我们没有关于列表内容的信息,我们必须为它们分配一个不同的类型变量 - b

    func :: Num a => [b] -> ? -> a
    
  3. 识别用于确定其余部分的函数,或者为已经找到的东西获取更专业的类型

    这里我们有2个信息,一个是(+)运算符,(f h) - 因为haskell中的空白字符表示函数应用,我们得到h的类型必须是函数ff h的结果与(+) :: Num a => a -> a -> a一起使用(请注意,两个参数必须具有相同的类型以及结果)和{{1}的结果}(func t f)我们得到的目标类型为a,因此f

  4. 撰写本文我们得到了

    f :: b -> a