I am writing an interpreter, and I would like to have a function that takes a function with normal parameters and converts it to a function that works with the interpreter. For example:.
add :: Monad m => Int -> Int -> m Value
let myadd = convert add :: Monad m => [Value] -> m Value
I have created several classes that actually do this as long as it m
is specific, but I need the result in order to be of type m Value
, and not, for example. IO Value
(I need to use it in two different monads).
data Value = VInteger Int deriving (Show)
class MyArg a where
fromValue :: Value -> Maybe a
instance MyArg Int where
fromValue (VInteger a) = Just a
fromValue _ = Nothing
class Monad m => MyFunc m r where
convert :: r -> [Value] -> m Value
instance Monad m => MyFunc m (m Value) where
convert f [] = f
convert _ _ = fail ""
instance (Monad m, MyArg a, MyFunc m r) => MyFunc m (a -> r) where
convert f (arg:rest)
| Just v <- fromValue arg = convert (f v) rest
convert _ _ = fail ""
I have this function to convert:
testfunc1 :: Monad m => Int -> Int -> m Value
testfunc1 num num2 = return $ VInteger (num + 10 * num2)
And it works:
main = do
let val = convert (testfunc1 :: Int -> Int -> Maybe Value) [VInteger 3, VInteger 5] :: Maybe Value
print val
However, it is not:
let val = convert testfunc1 [VInteger 3, VInteger 5] :: Maybe Value
And this, which is my usecase, is also not:
funclist :: Monad m => [ [Value] -> m Value ]
funclist = [
convert testfunc1
]
Mistake:
No instance for (GHC.Base.Monad m1)
arising from a use of ‘Main.testfunc1’
The type variable ‘m1’ is ambiguous
, - , m
m
, , , .