2014-03-29 3 views
3

코너 맥브라이드의 로스 패터슨 고전 용지 Applicative programming with effects 는 'matrice'전치 예를 도시 목록 : 함수 (여기 (:))를 쌍으로 만들고 elementwise를 입력하고 결과로 나온 출력 목록을 생성합니다.요청 명확화

v = [[1,2,3],[4,5,6]] 

주어 따라서

다음 나중에 논문에서 우리가 동일한 작업을 수행하려는 경우가

[[1,4],[2,5],[3,6]] 

에서

transpose v 

결과 우리 전치 예제 우리는 (Wadler, 1985) 도서관의 '성공의 목록을'피 에 모나드을 가지고 대신

transpose'' :: [[a]] -> [[a]] 
transpose''   [] = pure [] 
transpose'' (xs : xss) = pure (:) <*> xs <*> transpose'' xss 

여기 항복 '벡터화'를 지원하는 예를 Applicative [], pure = repeat(~) = zapp, transpose''를 취하여야한다 리스트의 "결정적이지 않은 계산 포인트 "을 사용하고 있습니다.이 함수는 회전 입력에 함수 (여기 (:))를 적용합니다.

따라서

[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]] 

에서

transpose'' v 

결과는 내가 미묘한 지점을 놓치고 생각합니다. 나는 transpose이 목록의 콜렉션 시점을 사용하여 실제로 "벡터"를 전치한다는 것을 알 수 있습니다. 그러나 transpose'' (목록의 비 결정적 계산 관점 사용)은 벡터 중첩과 아무 관련이없는 것처럼 보입니다.

즉, transposetranspose''은 서로 관련이없는 것 같습니다. 기능 - 다른 예. 내가 놓친 게 있니?

+0

코멘트 " 우리는 도서관의 '성공 목록'을 피해야 할 것입니다. "정확히 말하면 우리는"non-det 표현의 계산 적 관점 ". –

+0

got-thanks – haroldcarr

+0

정확히 보여준 동작을하는'Control.Applicative'에'newtype ZipList'가 있습니다. – Xeo

답변

2

pure = repeat 및 산출 (❄) = zapp, ...

이되지 표준 목록 인스턴스 입니다.하스켈에서이를 구현하기 위해, 우리는

newtype Zapp a = Zapp { runZapp : [a] } deriving (Functor) 
zcons :: a -> Zapp a -> Zapp a 
zcons x (Zapp xs) = Zapp $ x : xs 

instance Applicative Zapp where 
    pure = Zapp . repeat 
    Zapp a <*> Zapp b = Zapp $ zapp a b 

및 필요 다음

transpose'' :: Zapp (Zapp a) -> Zapp (Zapp a) 
transpose''   (Zapp []) = pure $ Zapp [] 
transpose'' (Zapp (xs : xss)) = pure zcons <*> xs <*> transpose'' xss 
+0

아야! 나는 더 자세히 읽을 필요가 있습니다. - 당신이 지적했듯이, 내가 왜 '순수 = 반복'을 놓 쳤기 때문에 나는 명확하지 않은지 ... - 고마워요! – haroldcarr

+0

제 방어도로,이 논문의 나머지 부분과 다른 것을 의미하는이 한 점에서 관용구를 사용하고 있습니다. 아직도, 나는 맹목적으로 번역하고 있었다. .. – haroldcarr

1

당신은 Applicative 인스턴스가 pure = repeat<*> = zapp

instance Applicative [] where 
    pure = repeat 
    (<*>) = zapp 

transpose :: [[a]] -> [[a]] 
transpose   [] = pure [] 
transpose (xs : xss) = pure (:) <*> xs <*> transpose xss 

main = do 
    print . transpose $ [[1,2,3],[4,5,6]] 

가있는 첫 번째 예에 대해 나열된 인스턴스를 만들 경우 트랜스 포즈에서 조바꿈을 얻습니다.

,739,529,

하는 경우는, 대신에, 당신은 당신이 그 예 모두

[[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]] 

상용구를 얻을 []

instance Applicative [] where 
    pure x = [x] 
    fs <*> xs = [f x | f <- fs, x <- xs] 

transpose :: [[a]] -> [[a]] 
transpose   [] = pure [] 
transpose (xs : xss) = pure (:) <*> xs <*> transpose xss 

main = do 
    print . transpose $ [[1,2,3],[4,5,6]] 

의 정상 Applicative 인스턴스를 사용하는 것은 :

module Main (
    main 
) where 

import Prelude hiding (repeat) 

infixl 4 <*> 
class Applicative f where 
    pure :: a -> f a 
    (<*>) :: f (a -> b) -> f a -> f b 

repeat :: a -> [a] 
repeat x = x : repeat x 

zapp :: [a -> b] -> [a] -> [b] 
zapp (f : fs) (x : xs) = f x : zapp fs xs 
zapp _  _  = []