Haskell新手:返回类型不匹配

时间:2018-08-12 19:42:34

标签: haskell

我遇到了一个障碍,试图弄清楚为什么我不能编译以下代码。我正在定义几个函数以使用“ snoc”列表。 headS正常工作,但是在tailS函数中,我无法返回NilS,我想知道为什么。我知道这可能是一个非常基本的问题,但是我已经尝试使用谷歌搜索,但感到更加困惑。希望你能帮助我了解我在想什么。这是我的代码:

data ListS a = NilS
          |Snoc (ListS a) a deriving Show

headS :: ListS a -> a
headS NilS          = error "Empty List"
headS (Snoc NilS a) = a
headS (Snoc a b)    = headS a

tailS :: ListS a -> a
tailS NilS          = error "Empty List"
tailS (Snoc NilS a) = NilS

我收到以下错误:

* Couldn't match expected type `a' with actual type `ListS a0'
  `a' is a rigid type variable bound by
    the type signature for:
      tailS :: forall a. ListS a -> a
    at Ejercicio01.hs:9:1-21
* In the expression: NilS
  In an equation for `tailS': tailS (Snoc NilS a) = NilS
* Relevant bindings include
    a :: a (bound at Ejercicio01.hs:11:18)
    tailS :: ListS a -> a (bound at Ejercicio01.hs:10:1)
   |
11 | tailS (Snoc NilS a) = NilS
   |                       ^^^^
Failed, no modules loaded.

提前感谢您的时间,

1 个答案:

答案 0 :(得分:3)

那么编译器是正确的。您的函数的类型签名是:

tailS :: ListS a -> a

因此,输出类型应为a。但是在这里,您将其写为返回值NilS。现在NilSListS a类型的数据构造函数。因此两者不匹配:您的签名表明您将返回“列表”类型的 element ,但是在函数定义中,您将返回一个列表(实际上可能会包装其他类型的元素)

您可能想要返回a元素,而不是NilS,所以:

tailS :: ListS a -> a
tailS NilS = error "Empty List"
tailS (Snoc NilS a) = a

但是还有另一个问题。如果我们使用-Wincomplete-patterns进行编译,则编译器将告诉您存在涵盖的模式:Snoc (Snoc _ _) _模式。在最后一行中,您写了tailS (Snoc NilS a),因此将其限制为Snoc的第一项为NilS。不管“前缀列表”是什么,这都是没有必要的,尾部始终是第二个参数,因此我们可以使用以下方法解决此问题:

tailS :: ListS a -> a
tailS NilS = error "Empty List"
tailS (Snoc _ a) = a