가 무엇을 기억하는 것이 좋다이 질문에 대답하기 위해 foldr
및 map
않습니다.
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
)을 두 개 더 얻습니다.
'foldr' 유형이 잘못되었으므로'(a -> b -> b) -> b -> [a] -> b'이어야합니다. –