Я взял следующий генератор дерева:
genTree0 :: MonadGen m => m (Tree String)
genTree0 =
Gen.recursive Gen.choice
[ Node "X" [] ]
[ Node "X" <$> Gen.list (Range.linear 0 20) genTree0 ]
и переписал его в состояние с состоянием:
genTree1 :: (MonadGen m, MonadState Int m) => m (Tree String)
genTree1 =
Gen.recursive Gen.choice
[ (`Node` []) <$> next ]
[ Node <$> next <*> Gen.list (Range.linear 0 20) genTree1 ]
where
next :: MonadState Int m => m String
next = fmap show (get <* modify (+1))
Но тогда как я мог прежде написать, например:
Gen.sample genTree >= putStrLn . drawTree
Я больше не могу делать это с версией с состоянием, потому что, конечно, я не инициализировал состояние:
> Gen.sample genTree
<interactive>:149:12: error:
• No instance for (MonadState Int Identity)
arising from a use of ‘genTree’
Попытка исправить это (предполагая, но не будучи полностью убежденной, что GenT
и StateT
коммутируют),
> Gen.sample (evalStateT genTree 0)
<interactive>:5:23: error:
• Could not deduce (MonadGen
(StateT Int (Hedgehog.Internal.Gen.GenT Identity)))
Я думаю, что есть очень маленькая, последняя часть, связанная с семействами типов, которую я не лажу.Что бы это могло быть?Если, например, я добавлю
genTree1 :: ( MonadGen m
, MonadState Int m
, GenBase m ~ Identity)
=> m (Tree String)
(просто потому, что я видел это раньше)
Вместо этого я получу еще одну ошибку,
> Gen.sample (runStateT genTree 0)
<interactive>:15:23: error:
• Couldn't match type ‘GenBase (StateT Int (GenT Identity))’
with ‘Identity’
К сожалению, вВ этот момент я просто начинаю неправильно угадывать, какое ограничение применять.
Обновление: В другом ключе я пытался создать определенный стек монадных преобразователей, начиная с genTree0
и genTree1
имеют довольно общие подписи:
newtype StateGen s a = StateGen { runStateGen :: StateT s (GenT IO) a }
deriving ( Functor, Applicative, Monad
, MonadState s
, MonadGen
, MonadIO
)
, но это также немного неправильно по отношению к.по крайней мере MonadGen
.
Что я должен здесь напечатать, чтобы начать, и еще лучше, где я могу научиться лучшему способу, чем гадание?