이것은 내가 어딘가에 왔지만 이것이 어떻게 작동하는지 알고 싶어하는 코드입니다.
findIndices :: (a -> Bool) -> [a] -> [Int]
findIndices _ [] = []
findIndices pred xs = map fst (filter (pred . snd) (zip [0..] xs))
출력 : findIndices (== 0) [1,2,0,3,0] == [2,4] 여기서 pred는 (== 0)이고 xs는 [1,2,0,3,0]입니다.
나는 내 이해의 일부를 보여줄 것이다 :
(zip [0..] xs)
위의 행은 목록의 모든 항목에 인덱스를 넣습니다. 위에 주어진 입력의 경우 다음과 같습니다. [(0,1), (1,2), (2,0), (3,3), (4,0)]
(pred . snd)
나는 이것이 pred (snd (x))와 같은 것을 의미한다는 것을 알았습니다. 내 질문은 x가 zip 줄에서 작성된 것입니까? 나는 예에 기대어 있지만 내 추측은 희미합니다.
다음은 fst와 snd에 대한 나의 이해입니다. 알아
fst(1,2) = 1
과
snd(1,2) = 2
이 두 명령은 코드에서 어떻게 의미가 있습니까?
필터에 대한 이해는 조건과 일치하는 항목 목록을 반환한다는 것입니다. 예를 들어
listBiggerThen5 = filter (>5) [1,2,3,4,5,6,7,8,9,10]
[6,7,8,9,10]을 줄 것이다
내지도에 대한 이해는 목록의 모든 항목에 기능을 적용한다는 것입니다. 예를 들어
times4 :: Int -> Int
times4 x = x * 4
listTimes4 = map times4 [1,2,3,4,5]
줄 것이다 [4,8,12,16,20]
전체적으로 어떻게 작동합니까? 나는 지금까지 내가 아는 것에 포괄적 이었지만 조각을 합칠 수는 없다고 생각합니다. 아무도 나를 도울 수 있습니까?
답변
Haskell에서는 다음 과 같이 말하고 싶습니다 . 실제로 조각은 유형에서 해당 유형으로가는 전선으로 연결되는 것처럼 연결됩니다.
(먼저 기능 구성 은 다음과 같습니다.
(f >>> g) x = (g . f) x = g (f x)
(f >>> g) = (g . f) = \x -> g (f x)
및 함수 조성물 타입 추론 규칙 이다 :
f :: a -> b -- x :: a
g :: b -> c -- f x :: b
------------------------- -- g (f x) :: c
f >>> g :: a -> c
g . f :: a -> c
이제)
findIndices :: (b -> Bool) -> [b] -> [Int]
findIndices pred = \xs -> map fst ( filter (pred . snd) ( zip [0..] xs ))
= map fst . filter (pred . snd) . zip [0..]
= zip [0..] >>> filter (snd >>> pred) >>> map fst
---------------------------------------------------------------------------
zip :: [a] -> [b] -> [(a, b)]
zip [0..] :: [b] -> [(Int,b)]
---------------------------------------------------------------------------
snd :: (a,b) -> b
pred :: b -> Bool
------------------------------------
(snd >>> pred) :: (a,b) -> Bool
---------------------------------------------------------------------------
filter :: (t -> Bool) -> [t] -> [t]
filter (snd >>> pred) :: [(a,b)] -> [(a,b)]
filter (snd >>> pred) :: [(Int,b)] -> [(Int,b)]
---------------------------------------------------------------------------
fst :: (a, b) -> a
map :: (t -> s) -> [t] -> [s]
map fst :: [(a,b)] -> [a]
map fst :: [(Int,b)] -> [Int]
전체적으로
zip [0..] :: [b] -> [(Int,b)]
filter (snd >>> pred) :: [(Int,b)] -> [(Int,b)]
map fst :: [(Int,b)] -> [Int]
---------------------------------------------------------------------------
findIndices pred :: [b] -> [Int]
당신은 물었습니다,이 조각들은 어떻게 맞습니까?
이것이 방법입니다.
함께 지능형리스트 , 함수는 다음과 같이 작성
findIndices pred xs = [ i | (i,x) <- zip [0..] xs, pred x ]
의사 코드는 다음과 같습니다.
“결과 목록이 포함되어 i
각각 (i,x)
의 zip [0..] xs
그러한 pred x
보유” .
n
-long 을 돌려서 이것을합니다
xs = [a,b,...,z] = [a] ++ [b] ++ ... ++ [z]
으로
[0 | pred a] ++ [1 | pred b] ++ ... ++ [n-1 | pred z]
곳 [a | True]
이다 [a]
하고 [a | False]
있다 []
.
답변
나는 이것이 다음과 같은 것을 의미한다는 것을 알았다
pred (snd (x))
. 내 질문은 x가 zip 줄에서 작성된 것입니까? 나는 예에 기대어 있지만 내 추측은 희미합니다.
글쎄 pred . snd
, 의미 \x -> pred (snd x)
합니다. 따라서 이것은 기본적으로에 요소를 매핑하는 함수를 구성 x
합니다 pred (snd x)
.
따라서 표현은 다음과 같습니다.
filter (\x -> pred (snd x)) (zip [0..] xs)
여기에서 x
이렇게하여 생성 된 2- 튜플이다 zip
. 그래서 알고하기 위해 (0, 1)
, (1,2)
, (2, 0)
, 등의 결과에 유지되어, snd x
이 2 튜플 (지금의 두 번째 요소 걸릴 것입니다 1
, 2
, 0
, 등)을하고 있는지 확인 pred
그쪽 요소에 대한 만족 여부입니다. 만족하면 요소를 유지하고 그렇지 않으면 해당 요소 (2- 튜플)가 필터링됩니다.
경우에 따라서 (== 0)
는 IS pred
icate, 다음 filter (pred . snd) (zip [0..] xs)
2 튜플이 포함됩니다 [(2, 0), (4, 0)]
.
그러나 이제 결과는 2- 튜플 목록입니다. 인덱스를 원한다면 어떻게 든 2 튜플 과이 2 튜플의 두 번째 요소를 제거해야합니다. 우리는 그것을 위해 사용 fst :: (a, b) -> a
합니다 : 이것은 첫 번째 요소에 2- 튜플을 매핑합니다. 목록은 그래서 [(2, 0), (4, 0)]
, map fst [(2, 0), (4, 0)]
돌아갑니다 [2, 4]
.