Home > other >  Can you access fromList within a Haskell function, without including the type in the function declar
Can you access fromList within a Haskell function, without including the type in the function declar

Time:11-07

I have a function declaration of:

iexec :: Instr -> Config -> Config
iexec (LOADI x) (counter, memory, stack) = (counter 1, memory, x:stack)

with Instr and Config being new Typeclasses. I want this to work like so:

>iexec (LOADI 5) (0, empty, [])
>(1, fromList [], [5])

My issue is that I don't know how to return the fromList of the memory, everything else is working. I tried doing

iexec (LOADI x) (counter, memory, stack) = (counter 1, Map.fromList memory, x:stack)

however I get an error, which varies based on the input, but it basically boils down to I don't know the correct syntax for this functionality, or I cannot access the fromList within a function. Anything to point me in the right direction would be helpful, thank you.

EDIT: As requested:

type Config = (Int, [Val] ,[Val])

where Val is an Int. The error message when just using memory is:

error:
    • Variable not in scope: empty :: [Val]
    • Perhaps you meant ‘mempty’ (imported from Prelude)
  |
9 | main = print (iexec (LOADI 5) (0, empty, []))

CodePudding user response:

If you write a type signature that says you return a list, then you cannot return a map instead. So the answer to the question in the title is "No, you can't do that.".

There are a variety of options for alternative plans. One would be to parameterize your Config type. Assuming you have imported your favorite map implementation module as M, that would look like this:

type Config2 f = (Int, f Val, [Val])

iexec2 :: Instr -> Config2 [] -> Config2 (M.Map Int)
iexec2 (LOADI x) (counter, memory, stack) = (counter 1, M.fromList (zip [0..] memory), x:stack)

main = print (iexec2 (LOADI 5) (0, [], []))

Another option would be to just change your Config type to always be a map:

type Config3 = (Int, M.Map Int Val, [Val])

iexec3 :: Instr -> Config3 -> Config3
iexec3 (LOADI x) (counter, memory, stack) = (counter 1, memory, x:stack)

main = print (iexec3 (LOADI 5) (0, M.empty, []))

There are further options, but I think these two are the cleanest.

  • Related