【问题标题】:Haskell types and signaturesHaskell 类型和签名
【发布时间】:2016-01-01 05:37:45
【问题描述】:

我正在准备有关 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 还是?以及如何将两条线混合在一起?

【问题讨论】:

  • @soon 感谢编辑,这样更易​​读
  • 永远欢迎你!

标签: haskell types functional-programming integer


【解决方案1】:
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 ... 的结果中

所以,func 的类型是:

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

【讨论】:

  • 好的,谢谢,所以在 (f h) 中,haskell 使用参数 h 调用 f,然后将结果添加到 code( (func t f) ) 的结果中?对吗?
【解决方案2】:

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

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

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

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

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

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

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

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

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

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

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

组成这个我们得到

func :: Num a => [b] -> (type-of-f) -> a
func :: Num a => [b] -> (b -> a) -> a

【讨论】:

  • 好的,我可以为另一个功能做这件事吗,func2 1 (h : t) = h ; func2 n (h : t ) = func2 (n-1) tfunc2 :: Num a => a ->[b] -> b 用于第一行,因为 1 是数字类型,(h : t) 是列表,而 h 是列表的第一个元素。第二行是func2:: Num a=> a -> [b] -> ? 也许是第一行的结果是b?所以完整的东西是func2::Num a => a ->[b] -> b。对吗?
  • 似乎很正确,除了基本情况 '1' 暗示 (Eq a) 的实例似乎,我认为这是因为您可以在 if (n == 1) …then…else 表达式中翻译此表达式
  • 顺便说一句 - 您可以在文件中键入 func2 定义 - 使用 ghci myfile.hs 将其加载到 ghci 中,然后 :t func2 以查看您的推理是否正确
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 1970-01-01
  • 2011-01-06
  • 2014-04-15
  • 1970-01-01
相关资源
最近更新 更多