Nikita Hismatov
Nikita Hismatov

Reputation: 1656

Haskell: What is the difference between (+1) and (\x->x+1)?

Is there a difference between these two functions?

ghct says:

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

But

When I used (+1) syntax in this piece of code:

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
                -- ...

prelude (as well as compiler) said:

> :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.

What am I doing wrong? sorry if code is not-so-cool (full source here: https://github.com/nskeip/bf/blob/a755b2d27292593d63fe1e63c2a6e01cebc73520/BrainFuck.hs)

Upvotes: 13

Views: 2269

Answers (4)

David Unric
David Unric

Reputation: 7719

Instead of subtract the decrement expression can be written directly also as (+(-1)) .

Upvotes: 4

sepp2k
sepp2k

Reputation: 370425

There is no difference between (+1) and \x -> x + 1 and if you look closely, (+1) isn't what's causing your error. (-1) is. And that's because unlike (+1), (-1) is not an operator section, it's negative one.

Upvotes: 4

dflemstr
dflemstr

Reputation: 26167

This code:

(-1)

... doesn't mean the same thing as this code:

\ x -> x - 1

- is a special case in Haskell; it is the only prefix operator in the language. When you write (-1), you get "negative one" which is a number, and not "subtract one" which is a function.

You should use subtract 1 to get what you need.

Upvotes: 22

Joni
Joni

Reputation: 111379

Your problem is not with (+1), it's with (-1):

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

-1 is a number! Try with apply (\x -> x-1) b or apply (subtract 1) b.

Upvotes: 11

Related Questions