Press J to jump to the feed. Press question mark to learn the rest of the keyboard shortcuts
View
49 points · 10 days ago

Seems like George got a little too curious

2 points · 1 month ago · edited 1 month ago

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.

see more
1 point · 1 month ago · edited 1 month ago

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.

1 point · 1 month ago · edited 1 month ago

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.

see more

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.

see more
Original Poster1 point · 2 months ago

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.

see more
Original Poster1 point · 2 months ago

Woops, I'll change that when I get time; thanks again!

Load more comments

Jokes on them, I use Emacs

Ninjacop123 commented on •

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

twitch.tv/ninjacop123 - Spongebob Creature From the Krusty Krab and Battle for Bikini Bottom speedruns

7 points · 6 months ago

Op did this for the upvotes

see more
Original Poster2 points · 6 months ago

I can't drive, and I don't have a car lol

2

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.

2
2 comments
u/Ninjacop123
Karma
11,101
Cake day
September 7, 2016
Trophy Case (1)
Two-Year Club