2012-02-02 2 views
3

현재 하스켈을 둘러보고 있습니다. 하스켈 (그리고 함수 언어)에 대한 나의 지식은 여전히 ​​낮지 만 나는 그것에 대해 연구 중이다. 정말로 나를 귀찮게하는 것은 단순한 작업 인 깊이 당 1 배의 중첩 목록 접기입니다.하스켈 폴딩 중첩리스트

fcalc = foldr (\x y -> (foldr (**) 1 x) * (foldr (**) 1 y)) [1.0, 1.0] [[2.0, 3.0], [4.0, 5.0]] 

: 2^3 * 4^5 여기서 ^는 람다 폴드에 의해 수행됩니다. 슬프게도 작동하지 않습니다.

Occurs check: cannot construct the infinite type: t0 = [t0] 
In the third argument of `foldr', namely `y' 

I는 주로 변수가 예로서 이용 된 것을 나타내는 소정의 "무한 형"오류에 대한 비트를 읽은 요소 대신 목록이었습니다. 이것은 나를 바깥 접기의 두 번째 매개 변수를 문제로 생각했지만 성공하지는 못하게했다. 나는 그것을 얻지 못한다. :/

+1

글쎄, 난 궁금해 이것에 대해 잘못된 방향으로가는 것은 아닙니다. 무엇보다도, 당신은 나의 엄지 손가락 법칙 중 하나를 깨고 있습니다. 문제를 직접 해결하기 위해 접기를 사용하지 않고, 문제를 해결하기 위해 중간 추상화를 구현하는 데 사용합니다. 둘째, 목록 및 중첩 목록이 실제로 수행하려는 작업에 적합한 데이터 구조인지 궁금합니다. 일종의 추상 구문 트리가 제공하는 문제 영역을 더 잘 처리하고 있다는 느낌이 들게됩니다. –

답변

4

귀하의 문제는 각 요소에 대해서도 수행하면서 접이식 내부의 누적 계산기에서 a^b 계산을 수행하려고한다는 것입니다. 당신이 정말로 원하는 것은 foldr의 각 단계의 출력은 다음 단계 (이 경우, 예를 들어 y 변수)의 두 번째 인수로 연결되어,

fcalc = foldr (\x y -> (foldr (**) 1 x) * y) 1 [[1.0, 1.0], [2.0, 3.0], [4.0, 5.0]] 

같은 것이 기억이다. foldr 단계가 숫자를 반환하기 때문에 y 변수는 이미 숫자이며 따라서 사용자는이를 넘을 수 없습니다.

+0

오, 이런 식으로 생각하면 어떻게 될까 ... 폴드에 대한 나의 이해를 고쳐 주셔서 고마워요. – Julian

1

하지 질문에 대한 답변,하지만 문제 해결하는 다른 방법 : 당신이 pointfree 편안하지 않은 경우,

haskell> sum $ map ((**) <$> (!! 0) <*> (!! 1)) xs 
1032.0 

을 또는 : 당신은 때로 믿을 경우

haskell> sum $ map (\x -> let (a:b:_) = x in a ** b) xs 
1032.0 
+2

첫 번째 두 요소 만보고 있다는 사실을 인코딩하려면 튜플을 대신 사용할 수 있습니다. –

+0

물론 컴파일 타임에 터플이 될 것임을 알 경우에만 가능합니다. – missingfaktor