I have some simple functions and I need makeMove to return IO():
toPole :: Show a => [a] -> [a] -> String
toPole fpole spole = show(head fpole:spole)
fromPole :: Show a => [a] -> String
fromPole fpole = show (tail fpole)
makeMove :: [a] -> [a] -> IO ()
makeMove [] _ = return ()
makeMove fpole spole = putStr (unwords p)
where p = [fromPole fpole, toPole fpole spole]
The idea is that I have two lists, and I want to move the first item of the list fpole
to the second list spole
, and print them as a nested list [[],[]]
with putStr
. Is there a way to achieve this? I've tried different things with the return type of toPole
and fromPole
, but figured it was easier to convert makeMove to IO() if the return type was String
.
The error I get arises from fromPole fpole
in where p = [fromPole fpole, ...
:
No instance for (Show a) arising from a use of ‘fromPole’
CodePudding user response:
makeMove
also needs the Show a
constraint. As it stands, you are saying that makeMove
can accept lists of any type as arguments, but then you try to pass those possibly Show
-less values to fromPole
.
makeMove :: Show a => [a] -> [a] -> IO ()
makeMove [] _ = return ()
makeMove fpole spole = putStr (unwords p)
where p = [fromPole fpole, toPole fpole spole]
A cleaner implementation wouldn't have either toPole
or fromPole
making any assumptions about the list elements; in fact, they are barely necessary. You can define makeMove
(arguably more clearly) without them.
transfer :: [a] -> [a] -> ([a], [a])
transfer (x:xs) ys = (xs, (x:ys))
makeMove :: Show a => [a] -> [a] -> String
makeMove fpole spole = let (fpole', spole') = transfer fpole spole
in unwords [fpole', spole']
showMove :: Show a => [a] -> [a] -> IO ()
showMove fpole spole = print (makeMove fpole spole)
Here, I've decomposed the function into three logical parts:
transfer
simply moves an element from one pole to the other.makeMove
creates aString
from the result oftransfer
showMove
outputs the result of the move.
As much work as possible is kept in pure functions, with only showMove
having any dependency on IO
.