0

我刚刚发现了 syb 库的强大功能并试图找到它的限制。

我有everywhere工作:

> :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 和 mkM 看起来很相似,我看不出 mkM 不适用于 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

甚至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 和 syb 0.7.2.1

4

1 回答 1

2

printMyInt有类型MyInt -> IO ()

mkM需要一个类型的参数b -> m b

存在不匹配,因为MyIntis not ()

你可以写

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

mkM pure是模棱两可的。mkM :: (Typeable a, Typeable b) => (b -> m b) -> a -> m a有两个类型参数,ab, 并且b在 中未确定mkM pure。不加约束就没有问题b,但是这里有一个Typeable b不固定就无法解决的约束b

于 2021-10-28T16:53:26.017 回答