没有(Num Bool)的实例来自字面'0'

时间:2018-03-01 15:01:23

标签: haskell

我的代码:

divisibleBy :: Int -> Int -> Bool
divisibleBy x y
    | mod x y == 0 = True
    | otherwise = False

isEven :: Int -> Bool
isEven x
    | (divisibleBy x 2) == 0 = True
    | otherwise = False

错误:

practical1.hs:30:28: error:
    • No instance for (Num Bool) arising from the literal ‘0’
    • In the second argument of ‘(==)’, namely ‘0’
      In the expression: (divisibleBy x 2) == 0
      In a stmt of a pattern guard for
                     an equation for ‘isEven’:
        (divisibleBy x 2) == 0
   |
30 |     | (divisibleBy x 2) == 0 = True    |  

divisibleBy功能有效,但isEven功能不起作用。我做错了什么?

1 个答案:

答案 0 :(得分:5)

错误信息已经说明了这一点。你写道:

isEven :: Int -> Bool
isEven x
    | (divisibleBy x 2) == 0 = True
    | otherwise = False

现在,如果我们对此进行类型检查,我们会发现(divisibleBy x 2)将返回Bool,并且您无法使用(==)和数字{Bool执行Bool 1}}在Haskell 是一个数字。)

为什么用== 0写这个对我来说并不是很清楚,我们可以把它写成:

isEven :: Int -> Bool
isEven x
    | (divisibleBy x 2) = True
    | otherwise = False

但现在它仍然不够优雅:我们不必检查条件是否适用于返回True和其他False,我们可以简单地返回定义,所以:

isEven :: Int -> Bool
isEven x = divisibleBy x 2

或者我们可以使用x

省略flip :: (a -> b -> c) -> b -> a -> c参数
isEven :: Int -> Bool
isEven = flip divisibleBy 2

同样适用于divisibleBy函数,我们可以将其重写为:

divisibleBy :: Int -> Int -> Bool
divisibleBy x y = mod x y == 0

或没有参数:

divisibleBy :: Int -> Int -> Bool
divisibleBy = ((0 ==) .) . mod

交换divisableBy

的参数

它看起来更像 Haskell 交换函数的参数,所以我们可以把它写成:

divisibleBy :: Int -> Int -> Bool
divisibleBy x y = mod y x == 0

从现在起我们可以定义一个函数divisibleBy 2,它将检查任何参数是否可以被2整除。

在这种情况下,isEven函数看起来像:

isEven :: Int -> Bool
isEven = divisibleBy 2