Home > database >  How to use syb mkM
How to use syb mkM

Time:10-29

I just discovered power of syb library and trying to find its limits.

I've got everywhere working:

> :set -XDeriveDataTypeable
> :set -XGeneralizedNewtypeDeriving
> import Data.Generics
> newtype MyInt = MyInt Int deriving (Show, Eq, Num, Ord, Data)
> incMyInt (MyInt i) = MyInt $ 1   i
> printMyInt (MyInt i) = putStrLn $ "MyInt = "    show i
> :t mkT incMyInt
mkT incMyInt :: Typeable a => a -> a

> :t mkM printMyInt

<interactive>:1:5: error:
    • Couldn't match type ‘()’ with ‘MyInt
      Expected type: () -> IO ()
        Actual type: MyInt -> IO ()

mkT and mkM look similar and I don't see the reason why mkM is not working for printMyInt

> :t mkM
mkM :: (Monad m, Typeable a, Typeable b) => (b -> m b) -> a -> m a
> :t mkT
mkT :: (Typeable a, Typeable b) => (b -> b) -> a -> a

even pure

:t mkM pure

<interactive>:1:1: error:
    • Could not deduce (Typeable b0) arising from a use of ‘mkM’
      from the context: (Monad m, Typeable a)
        bound by the inferred type of
                   it :: (Monad m, Typeable a) => a -> m a
        at <interactive>:1:1

ghc 8.10.7 and syb 0.7.2.1

CodePudding user response:

printMyInt has type MyInt -> IO ().

mkM expects an argument of type b -> m b.

There is a mismatch because MyInt is not ().

You can write

mkM (\x -> printMyInt x >> pure x)

mkM pure is ambiguous. mkM :: (Typeable a, Typeable b) => (b -> m b) -> a -> m a has two type parameters, a and b, and b is undetermined in mkM pure. It would not be a problem if b were not constrained, but here there is a Typeable b constraint that cannot be solved without fixing b.

  • Related