Seems like George got a little too curious
Remember that lists in Haskell are defined as
data [] a = [] | a : [a],
that is, they are build up by repeated applications of the "cons" constructor (:), and the nil constructor []. Whenever you see a list literal [x,y,z], you only have syntactic sugar for (x:y:z:[]). You are confusing these two in your pattern match.
Let's pattern match on the "wait" Atom.
eval env _ -- a `Values` goes here
eval env (List _) -- a (built-in Haskell) list goes here
eval env (List (Atom "wait" : _)) -- By the definition of (:) :: a -> [a] -> [a], a list(!) goes here
eval env (List (Atom "wait" : (_ : []))) -- Now we need a Values
eval env (List (Atom "wait" : (Number num : []))) -- Now simplify
eval env (List [Atom "wait", Number num])
But now we actually have three new problems. On the right-hand side, you want to use
threadDelay :: Int -> IO ().
So you need to either convert your Integer to Int via
fromInteger :: Num a => Integer -> a -- Specializing to Int
fromInteger :: Integer -> Int,
or modify your definition of the Number constructor accordingly.
Second problem. Your right-hand side does not return an IO (), it has to return a IOThrowsError Values.
In order to be able to obtain a value of this type, you have to do two things:
First, apply some function to threadDelay (fromInteger num) so that it type becomes IOThrowsError (). Then you can write
eval env (List [Atom "wait", Number num]) = do -- We're in the IOThrowsError monad now
changeType (threadDelay (fromInteger num))
somehowActuallyGetAValue
Secondly (or the third problem), you need to be able to actually return a result in eval. Do you know a function that may be of help? Why of course, it's eval. What you need to do is make your list pattern match more general:
eval env (List (Atom "wait": Number num: rest)) = do
_ (threadDelay (fromInteger num))
(ers :: [IOThrowsError Values]) <- mapM (eval env) rest -- Apply eval on [Values] instead of Values
let flattened = sequence ers :: IOThrowsError [Values] -- Hulk smash
values <- flattened
return (List values) -- Fit, damn it
Point being, either eval or Values need to be refined, since this was pretty awkward. You may make an IO a into an IOThrowsError a by using Control.Monad.Trans.Class.lift, making use of the fact that you are actually inside a "monad transformer stack".
This is probably all a little much to digest. I would recommend the "Monad Transformers Step by Step" tutorial, which builds up an interpreter like this.
Another thing to mention would be that nobody uses ErrorT anymore, you should use ExceptT (also from the transformers package) instead.
Hope this helps, I haven't tested any of this code since I'm lazy.
OK, now I'm in a predicament again. It's reporting that "_" is a hole: ErrorT -> langError IO a0, where a0 is ambiguous type variable, Couldn't match type Values with ErrorT BubbleError IO Values Expected type: [Values] in the (ers :: [IOThrowsError Values]) and Data constructor Values :: Values is not in scope in the return statement. I've tried to solve it on my own from what I know, but I am still having trouble. I've tried turning the "ers" statement to (erc :: [Values]), but it didn't really help, and I tried taking out the "_" in the _ (threadDelay (fromInteger num)). I've also tried assigning fromInteger (num) in a let statement and then using that local variable in threadDelay, but no dice.
Btw you may need to add
{-# LANGUAGE ScopedTypeVariables #-}
at the top for the type annotations to work. I just included them for emphasis. The whole example isn't something you should take too seriously.
Ok, thanks for the help!
Load more comments
it's still pretty basic atm.
So is mine, actually :-) Unfortunately I won't be looking at mine for at least another month, so it isn't going to progress anytime soon.
Gotcha; good luck whenever you start working on it again!
One last thing: on the wiki you list "bitwise operators" but you demonstrate logical operators.
Woops, I'll change that when I get time; thanks again!
Load more comments
Jokes on them, I use Emacs
LispWorks! Haha...
He's become the thing he sworn to destroy! RIP his Sequelitis
Thank god I'm a lisper
Must belong in the trash
Top 10 Moments before Utter Disaster
twitch.tv/ninjacop123 - Spongebob Creature From the Krusty Krab and Battle for Bikini Bottom speedruns
Op did this for the upvotes
I can't drive, and I don't have a car lol
If not, I have another 3DS, but I had soundhax on it a long while back... I didn't modify USUM on either 3DSs, though.
