Reputation: 1656
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
Reputation: 7719
Instead of subtract
the decrement expression can be written directly also as (+(-1))
.
Upvotes: 4
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
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
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