StateT와 비 결정론 모나드로 작업하는 법을 배우는 중 일부를 사용하여 정수의 파티션을 열거하기 위해 이들을 사용하는 함수를 작성하고 싶습니다. 정수를 재사용). 예를 들어, 4
의 인수를 전달하면 [[1,1,1,1],[1,1,2],[2,2],[1,3],[4]]
이됩니다 (고유성은 중요하지 않습니다. 작업 코드로 들어가는 것이 더 중요합니다).StateT와 non-determinism 모나드 : 간단한 예제
(또한 동적 프로그래밍과 파티션 계산을위한 함수 기반 솔루션 생성을위한 재귀 적 솔루션이 있다는 것을 알고 있습니다.이 연습의 목적은 StateT와 [ .])
여기 5보다 작거나 같은 모든 입력에서 작동하도록 설계되었다 내 시도입니다 :{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_GHC -Wall #-}
import CorePrelude
import Control.Monad.State.Lazy
sumState :: StateT Int [] [Int]
sumState = do
m <- lift [1..5]
n <- get <* modify (-m+)
case compare n 0 of
LT -> mzero
EQ -> return [m]
GT -> fmap (n:) sumState
runner :: Int -> [([Int],Int)]
runner = runStateT sumState
내가 디버깅에 도움이 runStateT
오히려 evalStateT
보다 사용하고는 (그것을 참조하는 것이 도움이 최종 상태 값). 앞서 말했듯이이 두 모나드를 함께 사용하는 올바른 방법을 먼저 이해하고 싶기 때문에 고유 한 파티션을 생성하는 것에 대해 너무 걱정하지 않습니다.
GHCi
에로드하고 runner 4
결과를 평가하면 위의 코드가이 출력을 생성하는 이유에 대해 혼란 스럽습니다.
[([4,3,2,1,1],-1),([4,3,2,1,2],-2),([4,3,2,1,3],-3),([4,3,2,1,4],-4),([4,3,2,1,5],-5),([4,3,2,1],-1),([4,3,2,2],-2),([4,3,2,3],-3),([4,3,2,4],-4),([4,3,2,5],-5),([4,3,1,1],-1),([4,3,1,2],-2),([4,3,1,3],-3),([4,3,1,4],-4),([4,3,1,5],-5),([4,3,1],-1),([4,3,2],-2),([4,3,3],-3),([4,3,4],-4),([4,3,5],-5),([4,2,1,1],-1),([4,2,1,2],-2),([4,2,1,3],-3),([4,2,1,4],-4),([4,2,1,5],-5),([4,2,1],-1),([4,2,2],-2),([4,2,3],-3),([4,2,4],-4),([4,2,5],-5),([4,1,1],-1),([4,1,2],-2),([4,1,3],-3),([4,1,4],-4),([4,1,5],-5),([4,1],-1),([4,2],-2),([4,3],-3),([4,4],-4),([4,5],-5)]
내가 뭘 잘못하고 있니? 파티션을 열거하기 위해 StateT와 []를 결합하는 올바른 방법은 무엇입니까?
마음은 '(-m +)'로 인해 날아갑니다. 도대체 무슨 일이야? – MathematicalOrchid
'(-m +)'이 실제로하고있는 것을 말할 수는 없지만 의도를 설명 할 것입니다 : 4 개의 인수 (즉,'GHCi'에'러너 4 ')를 전달한다고합시다. 아이디어는'modify'가 m으로 표현되는 숫자 [1..5] 중 하나에 의해 현재 상태 (첫 번째 패스에서 '4')를 감소시킬 것이라는 것이다. 그런 다음 새 상태가 <0, > 0 또는 == 0인지 테스트합니다. <0이면 값을 무시합니다. > 0이면, 우리는 그 특정 브랜치의 파티션에 m을 앞에두고 (fmap (m :)), 헹굼/반복을하고, == 0이면 (return [m]을 통해) 브랜치를 종료한다. 우리는 그 지점에서 목표 합계에 도달했습니다. – iceman
@MathematicalOrchid 자연스럽게'(+)'에서'-m' 부분 적용입니다. 전통적으로 대신 '빼기'라고 쓰여졌습니다. –