Как использовать syb mkM

#haskell #ghc #ghc-generics #syb

Вопрос:

Я только что обнаружил мощь библиотеки syb и пытаюсь найти ее пределы.

У меня есть everywhere работа:

 gt; :set -XDeriveDataTypeable gt; :set -XGeneralizedNewtypeDeriving gt; import Data.Generics gt; newtype MyInt = MyInt Int deriving (Show, Eq, Num, Ord, Data) gt; incMyInt (MyInt i) = MyInt $ 1   i gt; printMyInt (MyInt i) = putStrLn $ "MyInt = "    show i gt; :t mkT incMyInt mkT incMyInt :: Typeable a =gt; a -gt; a  gt; :t mkM printMyInt  lt;interactivegt;:1:5: error:  • Couldn't match type ‘()’ with ‘MyInt’  Expected type: () -gt; IO ()  Actual type: MyInt -gt; IO ()   

mkT и mkM выглядят одинаково, и я не вижу причины, по которой mkM не работает для printMyInt

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

даже pure

 :t mkM pure  lt;interactivegt;: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) =gt; a -gt; m a  at lt;interactivegt;:1:1  

ghc 8.10.7 и syb 0.7.2.1

Ответ №1:

printMyInt имеет тип MyInt -gt; IO () .

mkM ожидает аргумент типа b -gt; m b .

Существует несоответствие, потому MyInt что его нет () .

Вы можете написать

 mkM (x -gt; printMyInt x gt;gt; pure x)  

mkM pure это двусмысленно. mkM :: (Typeable a, Typeable b) =gt; (b -gt; m b) -gt; a -gt; m a имеет два параметра типа a и b , и b не определен в mkM pure . Это не было бы проблемой, если b бы не было ограничений, но здесь есть Typeable b ограничение, которое невозможно решить без исправления b .