Haskell Forall错误非法符号

时间:2017-10-18 20:53:34

标签: haskell

我的程序中出现了这个错误:

Illegal symbol '.' in type
    Perhaps you intended to use RankNTypes or a similar language
    extension to enable explicit-forall syntax: forall <tvs>. <type>

我的节目是:

ex31 :: Eq a => [a] -> [a]
ex31 [] = []
ex31 (h:t) = complementar 0 (h:t)

complementar :: forall a. Eq a => Int -> [a] -> [a]
complementar _ [] = []
complementar x (h:t) = if (x / 2) == div x 2
                       then complementar (x+1) t
                       else h : complementar (x+1) t

1 个答案:

答案 0 :(得分:4)

标准Haskell不支持您尝试使用的forall语法。要使用它,您需要启用语言扩展程序,例如RankNTypes。有几种方法可以启用这些扩展,但最简单的方法是在源文件的顶部添加一行,如下所示:

{-# LANGUAGE RankNTypes #-}

在交互式提示符下的GHCi中,您可以执行以下操作:

> set -XRankNTypes

然而,在这种情况下,我不确定你为什么写:

complementar :: forall a. Eq a => Int -> [a] -> [a]

因为它等同于写作:

complementar :: Eq a => Int -> [a] -> [a]

这是标准的Haskell语法,不需要任何扩展。

您的程序的另一个问题是检查x是否是偶数(即(x / 2) == div x 2表达式)在Haskell中不起作用。除法运算符“/”不适用于整数,因此您必须先将x转换为浮点数。

这在这种情况下会起作用,但通常基于浮点数相等的测试是棘手的并且最好避免。检查一个整数是否可被另一个整除的更标准方法是查看整数除法后的余数是否为零,您可以使用rem函数执行此操作:

> 10 `rem` 2 == 0
True
> 7 `rem` 2 == 0
False
>

(如果您必须处理负数,则可能需要查看remmod之间的差异。)

在这种特殊情况下,您可以使用库函数:

> even 10
True
> even 7
False
>