В настоящее время я знаю, как сделать это двумя способами, и оба они вроде хаки.Первый - использовать неявные параметры:
{-# LANGUAGE ImplicitParams #-}
import Control.Monad.State
import Control.Monad.Identity
import Data.Sequence
import qualified Data.Set as Set
data LowerSketchData = LowerSketchData (Set.Set Int)
type LowerMonadT m = StateT (Seq SketchAST) (StateT (Seq SketchAST) m)
data SketchAST = SketchAST
--run_astvn ::
-- LowerMonadT (StateT LowerSketchData Identity) β
-- -> Seq SketchAST
run_astvn x = ?get_ast2 $ runIdentity $
runStateT (runStateT (runStateT x empty) empty)
(LowerSketchData Set.empty)
-- where get_ast2 = snd . fst
Затем в ghci:
*Main> :t run_astvn
run_astvn
:: (?get_ast2::(((a, Seq a1), Seq a2), LowerSketchData) -> t) =>
StateT
(Seq a1) (StateT (Seq a2) (StateT LowerSketchData Identity)) a
-> t
Другой способ - дать намеренно неправильную сигнатуру типа и проверить, как компилятор жалуется.
import Control.Monad.State
import Control.Monad.Identity
import Data.Sequence
import qualified Data.Set as Set
data LowerSketchData = LowerSketchData (Set.Set Int)
type LowerMonadT m = StateT (Seq SketchAST) (StateT (Seq SketchAST) m)
data SketchAST = SketchAST
run_astvn ::
LowerMonadT (StateT LowerSketchData Identity) β
-> Seq SketchAST
run_astvn x = get_ast2 $ runIdentity $
runStateT (runStateT (runStateT x empty) empty)
(LowerSketchData Set.empty)
-- where get_ast2 = snd . fst
where get_ast2 :: (); get_ast2 = undefined
Это дает ошибку:
test.hs:13:19:
The first argument of ($) takes one argument,
but its type `()' has none
In the expression:
<snip>
Изменение неправильного типа на () -> ()
:
test.hs:13:30:
Couldn't match expected type `()'
with actual type `(((β, Seq SketchAST), Seq SketchAST),
LowerSketchData)'
In the second argument of `($)', namely
<snip>
Итак, теперь мы знаем, что тип должен выглядеть как (((β, Seq SketchAST), Seq SketchAST), LowerSketchData) -> ()
.Одна последняя итерация избавляет от финальной ()
, потому что компилятор жалуется, что:
test.hs:13:19:
Couldn't match expected type `Seq SketchAST' with actual type `()'
In the expression:
<snip>
... поэтому другая ()
должна быть Seq SketchAST
.