Haskell:(+ 1)和(\ x-> x + 1)有什么区别?

时间:2012-02-29 18:11:27

标签: haskell functional-programming

这两个功能有区别吗?

ghct说:

Prelude> :t (+1)
(+1) :: Num a => a -> a
Prelude> :t \x->x+1
\x->x+1 :: Num a => a -> a

但是

当我在这段代码中使用(+ 1)语法时:

data B = B { 
    pos :: Int, 
    cells :: [Int] 
} deriving (Show)

createB :: Int -> B
createB n = B 0 (take n $ repeat 0)

size :: B -> Int
size b = length $ cells b

get_curr :: B -> Int
get_curr b = (cells b) !! (pos b)

apply :: (Int -> Int) -> B -> B
apply f b = let n = pos b
                h = take n $ cells b       -- head
                t = drop (n + 1) $ cells b -- tail
                in B n $ h ++ [f (get_curr b)] ++ t

-- ...
eval :: [Char] -> StateT B IO ()
eval [] = return ()
eval (x:xs) = do
                b <- get

                put $ case x of
                        '+'         -> apply (+1) b
                        '-'         -> apply (-1) b
                        '>'         -> fwd b
                        '<'         -> back b
                        otherwise   -> b
                -- ...
前言(以及编译器)说:

> :load BrainFuck.hs 
[1 of 1] Compiling BrainFuck        ( BrainFuck.hs, interpreted )

BrainFuck.hs:49:40:
    No instance for (Num (Int -> Int))
      arising from the literal `1'
    Possible fix: add an instance declaration for (Num (Int -> Int))
    In the expression: 1
    In the first argument of `apply', namely `(- 1)'
    In the expression: apply (- 1) b
Failed, modules loaded: none.

我做错了什么? 抱歉,如果代码不那么酷(完全来源:https://github.com/nskeip/bf/blob/a755b2d27292593d63fe1e63c2a6e01cebc73520/BrainFuck.hs

4 个答案:

答案 0 :(得分:22)

此代码:

(-1)

...与此代码的含义不同:

\ x -> x - 1

-是Haskell的一个特例;它是该语言中唯一的前缀运算符。当你写(-1)时,你得到的是“负一”,这是一个数字,而不是“减一”这是一个函数。

您应该使用subtract 1来获取所需内容。

答案 1 :(得分:11)

问题不在于(+1),而在于(-1)

Prelude> :t (-1)
(-1) :: Num a => a

-1 is a number!尝试使用apply (\x -> x-1) bapply (subtract 1) b

答案 2 :(得分:4)

(+1)\x -> x + 1之间没有区别,如果仔细观察,(+1)不会导致您的错误。 (-1)是。这是因为与(+1)不同,(-1)不是运算符部分,而是负数。

答案 3 :(得分:4)

而不是subtract,减量表达式也可以直接写为(+(-1))