의 내가 지금 계산 모나드 명령을 인수로 취하는 함수에서 모나드 변환기를 지원하는 가장 좋은 방법은 무엇입니까?
class A where
foo :: () -> ()
instance A IO where
foo x = do
print "prefix"
x
print "suffix"
있다고 가정 해 봅시다, 내가 예를 들어 인수를, "풀다"강제하고있어
foo
을 구현 내가, 그리고
instance A => A (MyMonadTransformerT γ)
를 작성한다고 가정 foo x = lift (foo (unlift x))
. 이 unlift
함수는 모나드 계산에 좋지 않을 수 있습니다. 주 변압기의 경우 프로그램 상태의 변경 사항을 잊어 버리게됩니다.
리프팅 함수를 사용하는 좀 더 일반적인 방법을 만드는 것으로 작동하며 t() -> t()
이라는 계산 결과를 얻습니다. 여기서 t
은 해제 된 (변환 된) 모나드입니다.
class Monad => A' where
foo' :: Monad t =>
(forall z . z -> t z) -- lifting function
-> t()
-> t()
foo :: () -> ()
foo = foo' id
instance A' IO where
foo' lift x = do
lift (print "prefix")
x
lift (print "suffix")
instance A' => A' (StateT γ) where
foo' lift' x = foo' (lift' . lift) x
computation :: Num a => StateT a IO()
computation = do
foo (put 1 >> lift (print "middle"))
v <- get
lift $ print ("value", v)
run_computation :: Num a => IO a
run_computation = execStateT computation 0
질문. 이것이 최선의 방법입니까? 좀 더 일반적인 글을 쓸 수 있습니까? CPS 스타일 코드? 감사!!
가능한 한 [하스켈에서 고차 함수 해제하기] (0120-367-304) –
네, 중복 된 것 같아요. . "수업을 재촉하는 것"I와 luqui가 가장 좋은 것 같았습니다. – gatoatigrado