An ambiguous type variable in a variable parameter (printf-like function)

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 mis 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, , , .

+4
1

, , MyFunc m (a -> r) , Int -> Int -> m1 Value m1, m: - . .

funclist = [
    convert (testfunc1 :: Int -> Int -> m Value)
  ]

( , -XScopedTypeVariables , , forall m. funclist ).

+3

Source: https://habr.com/ru/post/1613293/


All Articles