Haskell类型签名与不同类型

时间:2015-01-16 05:52:44

标签: haskell type-signature

如果项目“X”连续出现两次,或者B)项目本身,如果它不与副本相邻。

示例:

encode ["A", "A", "A", "B", "C", "C", "B", "B", "B", "D"]
> [(3, "A"), "B", (2, "C"), (3, "B"), "D"]

适当的签名是什么?我试过这个:

data listItem a = (Integer, a) | a
encode :: (Eq a) => [a] -> [listItem a]

但是我收到了这个错误:

parse error in constructor in data/newtype declaration: (Integer, a) 

我偷看了这个问题的解决方案,它给了我这种类型的签名:

data ListItem a = Single a | Multiple Int a
    deriving (Show)
encode :: Eq a => [a] -> [ListItem a]

但是在使用这个简单的测试时

encode [x] = [x]

我收到错误:

Could not deduce (a ~ ListItem a)
from the context (Eq a)
  bound by the type signature for
             encode :: Eq a => [a] -> [ListItem a]
  at 99problems.hs:117:19-45
  `a' is a rigid type variable bound by
      the type signature for
        encode :: Eq a => [a] -> [ListItem a]
      at 99problems.hs:117:19
In the expression: x
In the expression: [x]

此问题的正确类型签名是什么?

1 个答案:

答案 0 :(得分:10)

根据我的理解,“99问题”集最初是为Prolog编写的,然后翻译成Lisp。那时......啊......音译到Haskell。不幸的是,在Lisp中有意义的事情在Haskell中并不总是那么有意义,所以从字面上理解问题描述会让你陷入困境。提示告诉你的是,不是试图编写一个产生类似[(3, "A"), "B", (2, "C"), (3, "B"), "D"]的列表的函数,而这在Haskell中是不可能的,你应该设法生成一个类似[Multiple 3 "A", Single "B", Multiple 2 "C", Multiple 3 "B", Single "D"]的列表。

建议的类型签名是正确的;你只需编写代码来匹配它。

注意

正如我所说,99问题集并不是非常Haskellian。它并不尊重Haskell代码的通常惯用风格,所以你应该将它作为如何编写Haskell代码的模型。例如,一个Haskell程序员(或者,对于这个问题,一个理智的Lisp程序员)可能只会产生一个(Int,a)对的列表,而不会打扰那些使一切更复杂,更不均匀的单个/多个废话。并且很可能在实际应用中速度较慢。

“99问题”的其他几种方式往往会打破Haskell编程的通常期望:

  1. 它倾向于以不同于Haskell程序员的顺序放置参数。如果函数采用列表和数字,Haskell程序员几乎总是将数字放在第一位,列表放在第二位; “99问题”倾向于反过来做。

  2. Haskell程序员几乎总是对列表,数组等使用基于0的索引。“99问题”似乎喜欢基于1的索引。