#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
.