2016-07-20 3 views
3

foldrDefaultfoldlDefault 기능을 사용하여 :는 "인스턴스의 값은 여기에 정의되지 않은, 그래서이 참조는 허용되지 않습니다"단지 <code>foldMap</code>을 정의하고 나는 그것을 위해 <code>Foldable</code> 인스턴스를 정의하려고 다음과 같은 간단한 트리 구조</p> <pre><code>data Tree a = Leaf | Branch (Tree a) a (Tree a) </code></pre> <p>을 정의한 후

instance treeFoldableInstance :: Foldable Tree where 
    foldr = foldrDefault 
    foldl = foldlDefault 
    foldMap f Leaf = mempty 
    foldMap f (Branch left a right) = foldMap f left <> (f a) <> foldMap f right 

을이 그러나 결과 :

The value of treeFoldableInstance is undefined here, so this reference is not allowed. 

foldlfoldr을 명시 적으로 정의하면 컴파일됩니다. 이 오류에 대한 문서는 게으름에 대해 알려주지 만 여기에 어떻게 적용됩니까?

답변

7

구성하려는 바로 사전을 요구하는 foldlDefaultfoldrDefault의 사용으로 인해 발생하며, PureScript는 엄격하게 평가되기 때문에 불가능합니다.

가장 쉬운 여기에서 수정과 같은 것을 시도하는 것입니다 : ETA-확대 foldrfoldl 정의, 그것은 desugared 코드로, 자기 참조를 지연함으로써

instance treeFoldableInstance :: Foldable Tree where 
    foldr f = foldrDefault f 
    foldl f = foldlDefault f 
    foldMap f Leaf = mempty 
    foldMap f (Branch left a right) = foldMap f left <> (f a) <> foldMap f right 

이된다 뭔가 같은 :

foldr = \f -> foldrDefault treeFoldableInstance f 

treeFoldableInstance에 대한 참조는 treeFoldableInstance의 선언이 아니라 f이 전달 된 후에 만 ​​평가됩니다.