문제

나는 기능을 구현하려고했다

every :: (a -> IO Bool) -> [a] -> IO Bool 

그것이 주제였습니다 이 질문. 나는 이것을하려고 노력했다 명백한 재귀없이. 다음 코드를 생각해 냈습니다

every f xs = liftM (all id) $ sequence $ map f xs

내 기능은 게으르지 않았기 때문에 작동하지 않았으므로 (질문에 필요 했음), 거기에 upvotes가 없습니다 :-).

그러나 나는 거기서 멈추지 않았다. 나는 기능을 만들려고 노력했다 포인트 프리 그래서 더 짧아지고 (아마도 더 시원 할 수도 있습니다). 논쟁 이후 f 그리고 xs 내가 방금 떨어 뜨린 표현의 마지막 것입니다.

every = liftM (all id) $ sequence $ map 

그러나 이것은 예상대로 작동하지 않았으며 실제로 전혀 효과가 없었습니다.

    [1 of 1] Compiling Main             ( stk.hs, interpreted )

    stk.hs:53:42:
        Couldn't match expected type `[m a]'
               against inferred type `(a1 -> b) -> [a1] -> [b]'
        In the second argument of `($)', namely `map'
        In the second argument of `($)', namely `sequence $ map'
        In the expression: liftM (all id) $ sequence $ map
    Failed, modules loaded: none.

왜 그런 겁니까? 나는 단순히 후행 기능 주장을 단순히 떨어 뜨릴 수 있다는 인상을 받았습니다.

도움이 되었습니까?

해결책

$의 정의는입니다

f $ x = f x

기능을 완전히 괄호로 만들어 봅시다.

every f xs = (liftM (all id)) (sequence ((map f) xs))

그리고 당신의 카레 버전 :

every = (liftM (all id)) (sequence map)

알다시피, 이것들은 동일하지 않습니다. 후행 기능 인수가 마지막으로 적용된 경우에만 삭제할 수 있습니다. 예를 들어,

f x = g c x

실제로입니다

f x = (g c) x

그리고 X에 (gc)를 적용하는 것은 마지막으로 나옵니다.

f = g c

응용 프로그램 연산자 $의 패턴은 종종 구성 연산자가된다는 것입니다. 포인트가없는 버전. 이 때문입니다

f $ g $ x

동일합니다

(f . g) $ x

예를 들어,

every f xs = liftM (all id) $ sequence $ map f xs

될 수 있습니다

every f xs = (liftM (all id) . sequence . map f) xs

그 시점에서 xs를 떨어 뜨릴 수 있습니다.

every f = liftM (all id) . sequence . map f

인수 f를 제거하는 것은 구성 연산자 앞에 적용되기 때문에 더 어렵습니다. DOT의 정의를 사용해 봅시다 http://www.haskell.org/haskellwiki/pointfree:

dot = ((.) . (.))

포인트가 있습니다

(f `dot` g) x = f . g x

그리고 정확히 모든 포인트를 무료로 만들기 위해 필요한 것입니다.

every = (liftM (all id) . sequence) `dot` map

안타깝게도 Haskell 유형 시스템의 제한으로 인해 명시 적 유형 서명이 필요합니다.

every :: (Monad m) => (a -> m Bool) -> [a] -> m Bool
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top