2017-01-11 3 views
0

하스켈에서 기능 구성을 이해하려고 시도하고 있습니다.하스켈 다중 기능 구성

ZVON http://zvon.org/other/haskell/Outputprelude/filter_f.html
에 따르면 필터 함수에는 bool 함수와 목록이라는 두 개의 인수가 있어야합니다.

filter (>5) [1,2,3,4,5,6,7,8] 5 이상 아무것도 반환 [6,7,8]

질문을하는 방법을 몇 가지 기능 조성물은 필터에 부울 전달에 다음 줄을 이용 하는가?

map fst . filter snd . assocs . soeA

는지도의 FST해서는 안됩니다. 필터 (== 참) snd. assocs. SOEA

제가 조성물의 처음 두 개의 기능을 실행 분석 인수 전달하려면 : assocs . soeA $ 9 복귀 [(0,False),(1,False),(2,True),(3,True),(4,False),(5,True),(6,False),(7,True),(8,False),(9,False)]

soe 9 복귀 여하튼 SOEA의 각 배열 요소에 불리언 값이 사용되고

[2,3,5,7], 그러나 이 구성이 어떻게 작동하는지 설명하는 도움은 대단히 감사하겠습니다.

전체 코드는 다음과 같습니다 `

module FastSeive where 

import Control.Monad 
import Control.Monad.ST 
import Data.Array.ST 
import Data.Array.Unboxed 



soeST :: forall s. Int -> ST s (STUArray s Int Bool) 
soeST n = do 
    arr <- newArray (0, n) True 
    mapM_ (\i -> writeArray arr i False) [0, 1] 
    let n2 = n `div` 2 

    let loop :: Int -> ST s() 
     loop i | i > n2 = return() 
     loop i = do 
      b <- readArray arr i 

      let reset :: Int -> ST s() 
       reset j | j > n = return() 
       reset j = writeArray arr j False >> reset (j + i) 

      when b (reset (2*i)) 

      loop (succ i) 

    loop 2 
    return arr 


soeA :: Int -> UArray Int Bool 
soeA n = runST (soeST n >>= freeze) 


soe :: Int -> [Int] 
soe = map fst . filter snd . assocs . soeA 


soeCount :: Int -> Int 
soeCount = length . filter id . elems . soeA 

`

답변

0

짧은 대답은 : 여기, sndBool -returning 기능 filter 예상하는 것입니다. 당신이 작성한 표현에서 : map fst . filter (==True) snd . assocs . soeA. sndfilter의 두 번째 인수가되고 (==True)은 첫 번째 인수가됩니다. 물론 filter이 이미 두 개의 인수에 적용되고 함수 합성에 사용할 수 없으므로 typecheck되지 않습니다. 더 이상 함수가 아닙니다. 더 이상 대답을


, 우리가 실제로 '무슨 일이 일어나고 있는지 알아의 정의 : 지금은 분명

(f . g) x = f (g x) 
-- In haskell, it is defined as being right associative 

-- Meaning that if we put explicit parenthesises, we'd have: 
soe = (map fst . (filter snd . (assocs . soeA))) 
-- That only really matters for the compiler, though, 
-- because we know function composition is associative. 

soe = map fst . filter snd . assocs . soeA 
-- "Un-pointfree-ing" it: 
soe x = (map fst . filter snd . assocs . soeA) x 
-- Applying (.)'s definition: 
soe x = map fst ((filter snd . assocs . soeA) x) 
-- Again: 
soe x = map fst (filter snd ((assocs . soeA) x)) 
-- And again: 
soe x = map fst (filter snd (asocs (soeA x))) 

sndfilter 것을'(.)을 적용 할 수있는 최초의 인수하면서 두 번째 인수 것 assocs (soeA x)의 평가 대상으로 평가하십시오.

하나 f . g . h를 기록 할 때보다 일반적으로,이 판독 할 수 오른쪽에서 왼쪽으로 제 다음 결과에이어서, 결과를 다음에, 그 인수에 fgh 적용 기능, 수율 최종 값 .


이제 더 이상 답변을 얻으려면 표현식의 유형이 유추되는 방식을 살펴볼 수 있습니다. sndBool - 복귀 함수 filter 인 이유는 snd :: (a, b) -> b의 유형 서명이 있더라도 나타납니다.

면책 조항 : 컴파일러 엔지니어링에 대한 배경 지식이 없습니다. 내가 사용할 용어가 부정확 할 수 있습니다.

filter의 유형은 (a -> Bool) -> [a] -> [a]입니다. snd의 유형은 (a, b) -> b입니다.

이들은 실제로 매개 변수화 된 유형입니다. 우리는 형식 매개 변수를 명시 적으로 만들 수 있습니다

filter :: forall a. (a -> Bool) -> [a] -> [a] 
snd :: forall a b. (a, b) -> b 
우리는 또한 우리가 다음에 쓸 것이다 무엇에 비 모호하게하기 위해 filter의 형식 인수의 이름을 바꿀 수 있습니다

:

filter :: forall c. (c -> Bool) -> [c] -> [c] 

filter 가져 먼저 snd에 적용됩니다. 따라서 c -> Boolfilter에서 (a, b) -> b, snd '유형으로 통합하고 통합 할 수 있습니다. 우리는이 방정식을 얻을 :

c -> Bool = (a, b) -> b 

=== 

c = (a, b) 
b = Bool 

=== 

c = (a, Bool) 
b = Bool 

우리는 assocs (soeA x)의 유형 [(Int, Bool)]이라고 가정합니다. filter의 두 번째 인수 유형 [c]을 가지고 있기 때문에, 우리는 더 통합 할 수 있습니다

[c] = [(Int, Bool)] 

=== 

c = (Int, Bool) 

를 이것은 또한 우리가 제공 :

(Int, Bool) = c = (a, Bool) 

=== 

a = Int 

그래서, 형 응용 프로그램 후, 우리는 우리의 하위 이러한 구체적인 유형을 얻기를 표현 :

filter :: ((Int, Bool) -> Bool) -> [(Int, Bool)] -> [(Int, Bool)] 
snd :: (Int, Bool) -> Bool 

음, 물론, 우리는 GHCi를 사용하거나 텍스트 편집기의 하스켈 플러그를 통해 하나, 그것에 대해 우리에게 얘기를 모두 함께 GHC의 형식 유추를 사용할 수도 에서.

+0

감사합니다. "soe x = map fst (filter snd ((assocs. soeA) x))") 괄호가있는 샘플은 "정말 도움이되었습니다. – brander