2013-02-02 2 views
5

그래서, 바로 그 지점으로 가자.지도. foldr 함수 구성 - Haskell

:t (map.foldr) 
(map.foldr) :: (a1 -> a -> a) -> [a] -> [[a1] -> a] 

[[a1] -> a] 란 무엇입니까? 난 정말이 구성을 이해하려고 노력 중이 야, 그래서 나는이 일을했다 :

-- map.foldr 

    map.foldr :: (a1 -> a -> a) -> [a] -> [[a1] -> a] 

    map :: (a1 -> b1) -> [a1] -> [b1] 
    (.) :: (y -> w) -> (x -> y) -> x -> w 
    foldr :: (a -> b -> b) -> b -> [a] -> b 

    y = (a1 -> b1)  w = ([a1] -> [b1]) 
    x = (a -> b -> b) y = (b -> [a] -> b) 

    y = (a1 -> b1) 
    y = (b -> [a] -> b) 
_________________________ 

어떤이 시점에 발생을? 고맙습니다!

+1

'foldr' 유형이 잘못되었으므로'(a -> b -> b) -> b -> [a] -> b'이어야합니다. –

답변

14

가 무엇을 기억하는 것이 좋다이 질문에 대답하기 위해 foldrmap 않습니다.

1 : 2 : 3 : [] 

액션 :

둘 중 더 복잡 정말 conses (:)와 단말 빈리스트의 체인, foldr이다

--    list to be folded 
--        v 
foldr :: (a -> b -> b) -> b -> [a] -> b 
--   ^  ^
--folding function  terminal value 

를 절첩 할 목록 입력을 갖는 foldr의 경우 및 [] 구성자를 폴딩 함수와 터미널 값으로 각각 바꿉니다.

foldr (+) 0 (1 : 2 : 3 : []) == 1 + 2 + 3 + 0 

map 함수는 간단하다.

map :: (a -> b) -> [a] -> [b] 
--  ^  ^
-- function   list 

그러나, 당신은 또한 기능을 복용하고 그것을 해제로 생각할 수 있습니다 : 그것은 생각하는 한 가지 방법은 목록의 모든 인수 기능을 기능과 목록을 복용하고, 적용과 같다

map :: (a -> b) -> ([a] -> [b]) 
--  ^   ^
-- function    function on lists 

는, map . foldr이 두 가지 기능을 구성하는 것은 무엇을 의미 하는가 :리스트 대신에 작용하는 기능이 될?이 단지 기능을 하나씩 적용하고 있습니다 - 특히를

(map . foldr) f == map (foldr f) 

당신은 적용하기 때문에 foldr 첫째, 당신은 기능 f :: a -> b -> b에 적용해야하며, 다른 기능을 다시 얻을 :

foldr f :: b -> [a] -> b 
--  ^ ^
--terminal val list to be folded 

map (foldr f) :: [b] -> [[a] -> b] 
--    ^  ^
--list of terminal vals  functions that fold lists 
이 유형은 이상하게 보이는

, BU :

이제 당신은 목록에 행동 할 수있는 기능을 리프트 map을 적용 그것은 유효합니다. 이제 단일 터미널 값 대신 터미널 값 목록을 제공하고 사용자가 제공 한 각 터미널 값에 대해 하나의 접음 함수 목록을 반환합니다.


은 분명 우리가 위의 방정식으로 그것을 대체 할 경우, 우리는

(map . foldr) (+) :: Num a => [a] -> [[a] -> a] 
--       ^  ^
--   list of terminal vals   functions that fold lists 

하면 얻을

(+) :: Num a => a -> a -> a 

입력이 특정 기능, (+), 볼 수 있도록하려면 이제 우리는 목록 [0, 1, 2]에 적용하여 세 가지 기능 목록을 얻습니다.

(map . foldr) (+) [0,1,2] :: Num a => [[a] -> a] 

이디언을 사용하여 목록의 각 함수를 특정 인수에 적용 할 수 있습니다. 숫자 목록이어야하며 [3,4,5]을 선택하겠습니다. 주의 깊게보기 :

> map ($[3,4,5]) ((map.foldr) (+) [0,1,2]) 
[12, 13, 14] 

[3,4,5]는 폴딩 기능으로 (+)를 사용하여 세 번 접힌 된 목록 및 다른 단말기 값을 각 시간 : 단말기 값이 0 경우

3 + 4 + 5 + 0 == 12 
3 + 4 + 5 + 1 == 13 
3 + 4 + 5 + 2 == 14 

, 우리는 단순히 얻을 값의 합 : 3 + 4 + 5 == 12. 터미널 값이 1 일 때 값의 합 (13)을 하나 더 얻고 터미널 값이 2 일 때 값의 합 (14)을 두 개 더 얻습니다.

+0

"map ($ x)"관용구에 대한 자세한 정보는 어디에서 찾을 수 있습니까? 나는 그것을 이해할 수 없다. 오, 그리고 고마워, 정말 도움이 :) – dehq

+1

'$'연산자는'f $ x = f x'에 의해 정의됩니다. 즉 왼쪽에있는 함수를 오른쪽에있는 인수에 적용합니다. 1. '$'연산자는 우선 순위가 가장 낮고 우선 순위가 가장 높은 함수 응용 프로그램과 달리 오른쪽을 연결하고 대신 왼쪽에 연결하여 fa $ gb $ hc를 쓸 수 있습니다. 2. fa (gb (hc))의 섹션 2. 당신은 섹션에서 그것을 사용할 수 있으므로'\a -> fa '대신'($ f)'를 쓸 수 있습니다. 따라서'map ($ x)'코드는'map (\ a -> x a)'와 같은 의미입니다. –

1
map.foldr :: (a1 -> a -> a) -> [a] -> [[a1] -> a] 

map :: (a1 -> b1) -> [a1] -> [b1] 
(.) :: (y -> w) -> (x -> y) -> x -> w 
foldr :: (a -> b -> b) -> b -> [a] -> b 

-- if you substitute: x = (a -> b -> b) y = (b -> [a] -> b) 
-- then you get for map :: (b -> ([a] -> b)) -> [b] -> [[a] -> b] 
-- so if composition operator applied: 
map . foldr :: (a -> b -> b) -> [b] -> [[a] -> b] 
2

은 중단 한 부분, y의 두 가지 정의가 동일해야합니다 계속하려면 : 함수 조성물이 공급 된

a1 = b 
b1 = [a] -> b 

:

y = (a1 -> b1) = (b -> [a] -> b) 
       = (b -> ([a] -> b)) 

그래서 우리는 그 결론을 내릴 수 있습니다 함수 인수이므로 결과 유형은 다음과 같습니다.

x -> w 
,

는하지만 우리는 알고

x = a -> b -> b 
w = [a1] -> [b1] = [b] -> [[a] -> b] 

그래서, 결과 유형은 다음과 같습니다에 합동

(x -> w) = ((a -> b -> b) -> ([b] -> [[a] -> b])) 
     = (a -> b -> b) -> [b] -> [[a] -> b] 

:

(a1 -> a -> a) -> [a] -> [[a1] -> a]