수색…


통사론

  1. 빈리스트 생성자

    [] :: [a]

  2. 비어 있지 않은리스트 생성자

    (:) :: a -> [a] -> [a]

  3. head - 목록의 첫 번째 값을 반환합니다.

    head :: [a] -> a

  4. 마지막 - 목록의 마지막 값을 반환합니다.

    last :: [a] -> a

  5. tail - 첫 번째 항목이없는 목록을 반환합니다.

    tail :: [a] -> [a]

  6. init - 마지막 항목이없는 목록을 반환합니다.

    init :: [a] -> [a]

  7. xs !! i - 목록 xs의 색인 i에서 요소를 반환합니다.

    (!!) :: Int -> [a] -> a

  8. n xs 취하기 -리스트의 n 번째 원소를 포함하는 새로운리스트를 반환한다. xs

    take :: Int -> [a] -> [a]

  9. map :: (a -> b) -> [a] -> [b]

  10. filter :: (a -> Bool) -> [a] -> [a]

  11. (++) :: [a] -> [a]

  12. concat :: [[a]] -> [a]

비고

  1. 유형 [a][] a 와 같습니다.
  2. [] 빈 목록을 만듭니다.
  3. [] 함수 정의 LHS에서 예 f [] = ... , 빈리스트 패턴이다.
  4. x:xs 는 원소 x 가리스트 xs 앞에 붙는리스트를 xs
  5. f (x:xs) = ... 비어 있지 않은 목록에 대한 패턴 일치입니다. 여기서 x 는 머리이고 xs 는 꼬리입니다.
  6. f (a:b:cs) = ...f (a:(b:cs)) = ... 는 동일합니다. 첫 번째 요소가 a 이고 두 번째 요소가 b 이고 나머지 목록이 cs 두 개 이상의 요소 목록에 대한 패턴 일치입니다.
  7. f ((a:as):bs) = ...f (a:(as:bs)) = ... 와 동일하지 않습니다. 전자는 목록의 비어 있지 않은 목록에 대한 패턴 일치 a , 머리의 머리 as 머리의 꼬리이며, bs 꼬리입니다.
  8. f (x:[]) = ...f [x] = ... 는 동일합니다. 정확히 하나의 요소 목록에 대한 패턴 일치입니다.
  9. f (a:b:[]) = ...f [a,b] = ... 는 동일합니다. 그것들은 정확하게 두 요소 목록에 대한 패턴 일치입니다.
  10. f [a:b] = ... 는 요소가 목록이기도 한 정확히 하나의 요소 목록에 대한 패턴 일치입니다. a 는 요소의 머리이고 b 는 요소의 꼬리입니다.
  11. [a,b,c](a:b:c:[]) . 표준 목록 표기법은 (:)[] 생성자에 대한 구문 식 설탕입니다.
  12. 당신이 사용할 수있는 all@(x:y:ys) 등 전체 목록을 참조하기 위해 all 대신 반복하는 (또는 당신이 선택하는 다른 이름) (x:y:ys) 다시.

리터럴 목록

emptyList     = []

singletonList = [0]               -- = 0 : []

listOfNums    = [1, 2, 3]         -- = 1 : 2 : [3]

listOfStrings = ["A", "B", "C"]

목록 연결

listA      = [1, 2, 3]

listB      = [4, 5, 6]

listAThenB = listA ++ listB       -- [1, 2, 3, 4, 5, 6]

(++) xs     [] = xs
(++) []     ys = ys
(++) (x:xs) ys = x : (xs ++ ys)

목록 기본 사항

Haskell Prelude에있는리스트의 타입 생성자는 [] 입니다. Int 형의 값을 보관 유지하는리스트의 형태 선언은, 다음과 같이 기술됩니다.

xs :: [Int]    -- or equivalently, but less conveniently,
xs :: [] Int

Haskell의리스트는 동 질적 시퀀스 이며 모든 요소는 같은 타입이어야한다. 튜플과 달리 목록 유형은 길이에 영향을받지 않습니다.

[1,2,3]   :: [Int]
[1,2,3,4] :: [Int]

리스트는 두 개의 생성자를 사용하여 생성됩니다 .

  • [] 빈 목록을 만듭니다.

  • (:) 은 "cons"라고 발음하며, 요소를 목록 앞에 추가합니다. Consing의 x (입력 값 상) a xs (동일한 타입의 값의리스트 a ) 그의 헤드 (첫 번째 요소)는 새로운 목록을 작성 x테일 (요소의 나머지 부분)은 xs .

다음과 같이 간단한 목록을 정의 할 수 있습니다.

ys :: [a]
ys = []

xs :: [Int]
xs = 12 : (99 : (37 : []))   
-- or  = 12 : 99 : 37 : []     -- ((:) is right-associative)
-- or  = [12, 99, 37]          -- (syntactic sugar for lists)

목록을 만드는 데 사용할 수있는 (++)(:)[] 재귀 적으로 정의됩니다.

목록 처리 중

목록을 처리하려면 목록 유형의 생성자에 패턴 일치를 간단히 지정할 수 있습니다.

listSum :: [Int] -> Int
listSum []          = 0
listSum (x:xs) = x + listSum xs

보다 정교한 패턴을 지정하여 더 많은 값을 일치시킬 수 있습니다.

sumTwoPer :: [Int] -> Int
sumTwoPer [] = 0
sumTwoPer (x1:x2:xs) = x1 + x2 + sumTwoPer xs
sumTwoPer (x:xs) = x + sumTwoPer xs

위의 예제에서 홀수 길이 목록이 인수로 주어진 경우를 처리하기 위해 더 철저한 패턴 일치를 제공해야합니다.

Haskell Prelude는 map , filter 등과 같은 목록을 처리하기위한 많은 내장 함수를 정의합니다. 가능한 경우 자체 재귀 함수를 작성하는 대신 이들을 사용해야합니다.

목록의 요소 액세스

목록의 n 번째 요소에 액세스합니다 (0부터 시작).

list = [1 .. 10]

firstElement = list !! 0           -- 1

참고 !! 부분 함수이므로 특정 입력에 오류가 발생합니다.

list !! (-1)     -- *** Exception: Prelude.!!: negative index  

list !! 1000     -- *** Exception: Prelude.!!: index too large

Data.List.genericIndex 는 오버로드 된 버전입니다 !! Integral 값을 인덱스로 받아들입니다.

import Data.List (genericIndex)

list `genericIndex` 4              -- 5

단일 연결 목록으로 구현되는 경우 이러한 작업에는 O (n) 시간이 소요됩니다. 인덱스로 요소에 자주 액세스하는 경우 벡터 패키지의 Data.Vector 또는 다른 데이터 구조를 사용하는 것이 좋습니다.

범위

범위 표기법을 사용하면 1에서 10까지 목록을 만드는 것이 간단합니다.

[1..10]    -- [1,2,3,4,5,6,7,8,9,10]

단계를 지정하려면 쉼표와 start 요소 뒤에 다음 요소를 추가하십시오.

[1,3..10]  -- [1,3,5,7,9]

Haskell은 항을 항상 항의 산술적 인 차이로 간주하고, 처음 두 요소와 상한보다 더 많이 지정할 수 없다는 점에 유의하십시오.

[1,3,5..10] -- error
[1,3,9..20] -- error

범위를 내림차순으로 생성하려면 항상 음수 단계를 지정하십시오.

[5..1]     -- []

[5,4..1]   -- [5,4,3,2,1]

하스켈은 엄격하지 않기 때문에 목록의 요소는 필요한 경우에만 평가되므로 무한한 목록을 사용할 수 있습니다. [1..][1..] 부터 시작하는 무한리스트입니다.이 목록은 변수에 바인딩되거나 함수 인수로 전달 될 수 있습니다.

take 5 [1..]   -- returns [1,2,3,4,5] even though [1..] is infinite

반올림 문제를 방지하기 위해 반올림 델타까지 스필 오버를 허용하기 때문에 부동 소수점 값이있는 범위를 사용할 때는주의하십시오.

[1.0,1.5..2.4]    -- [1.0,1.5,2.0,2.5] , though 2.5 > 2.4

[1.0,1.1..1.2]    -- [1.0,1.1,1.2000000000000002] , though 1.2000000000000002 > 1.2

범위는 숫자뿐만 아니라 Enum 형 typeclass를 구현하는 모든 유형에서 작동합니다. 열거 가능한 변수 a , b , c 가 있으면 범위 구문은 다음 Enum 메서드를 호출하는 것과 같습니다.

[a..]    == enumFrom a
[a..c]   == enumFromTo a c
[a,b..]  == enumFromThen a b
[a,b..c] == enumFromThenTo a b c

예를 들어 Bool 에서는

 [False ..]      -- [False,True]

후 공간을 주목 False 이 방지하기 위해 모듈 이름 자격으로 구문 분석하는 (즉, False.. 로 분석된다 . 모듈에서 False ).

목록의 기본 기능

head [1..10]       --    1

last [1..20]       --    20

tail [1..5]        --    [2, 3, 4, 5]

init [1..5]        --    [1, 2, 3, 4]

length [1 .. 10]   --    10

reverse [1 .. 10]  --    [10, 9 .. 1]

take 5 [1, 2 .. ]  --    [1, 2, 3, 4, 5]

drop 5 [1 .. 10]   --    [6, 7, 8, 9, 10]

concat [[1,2], [], [4]]   --    [1,2,4]

이것이 왼쪽 폴드가 구현되는 방법입니다. step 함수에서 인수의 순서가 foldr (오른쪽 접기)와 비교하여 어떻게 뒤집혀 있는지 확인하십시오.

foldl :: (b -> a -> b) -> b -> [a] -> b
foldl f acc []     =  acc
foldl f acc (x:xs) =  foldl f (f acc x) xs         -- = foldl f (acc `f` x) xs  

왼쪽 접기 foldl 은 왼쪽에 연결됩니다. 그건:

foldl (+) 0 [1, 2, 3]     -- is equivalent to ((0 + 1) + 2) + 3

그 이유는 foldl 은 다음과 같이 평가됩니다 ( foldl 의 귀납적 인 단계를보십시오).

foldl (+) 0 [1, 2, 3]                        --  foldl (+)    0   [ 1,   2,   3 ]
foldl (+) ((+) 0 1) [2, 3]                   --  foldl (+)   (0 + 1)   [ 2,   3 ]
foldl (+) ((+) ((+) 0 1) 2) [3]              --  foldl (+)  ((0 + 1) + 2)   [ 3 ]
foldl (+) ((+) ((+) ((+) 0 1) 2) 3) []       --  foldl (+) (((0 + 1) + 2) + 3) []
((+) ((+) ((+) 0 1) 2) 3)                    --            (((0 + 1) + 2) + 3)

마지막 줄은 ((0 + 1) + 2) + 3 . 이것은 (fab) 이 일반적으로 (a `f` b) 와 같기 때문에 ((+) 0 1) 은 특히 (0 + 1) 과 동일하기 때문입니다.

접는 사람

바로 접기가 구현되는 방식입니다.

foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f z []     = z
foldr f z (x:xs) = f x (foldr f z xs)              -- = x `f` foldr f z xs

오른쪽 접기 foldr 는 오른쪽에 연결됩니다. 그건:

foldr (+) 0 [1, 2, 3]      -- is equivalent to 1 + (2 + (3 + 0))

그 이유는 foldr 는 다음과 같이 평가됩니다 ( foldr 의 유도 단계를보십시오).

foldr (+) 0 [1, 2, 3]                        --          foldr (+) 0  [1,2,3]
(+) 1 (foldr (+) 0 [2, 3])                   -- 1 +        foldr (+) 0  [2,3]
(+) 1 ((+) 2 (foldr (+) 0 [3]))              -- 1 + (2 +     foldr (+) 0  [3])
(+) 1 ((+) 2 ((+) 3 (foldr (+) 0 [])))       -- 1 + (2 + (3 +  foldr (+) 0 []))
(+) 1 ((+) 2 ((+) 3 0))                      -- 1 + (2 + (3 +            0   ))

마지막 행에 해당 1 + (2 + (3 + 0)) 하기 때문에, ((+) 3 0) 과 동일하다 (3 + 0) .

`map`으로 변환하기

컬렉션의 내용 (목록 또는 무언가)을 변환하거나 변형하려고하는 경우가 많습니다. 하스켈에서 우리는 map 를 사용 map :

 -- Simple add 1
 map (+ 1) [1,2,3]
 [2,3,4]
 
 map odd [1,2,3]
 [True,False,True]
 
 data Gender = Male | Female deriving Show
 data Person = Person String Gender Int deriving Show

 -- Extract just the age from a list of people
 map (\(Person n g a) -> a) [(Person "Alex" Male 31),(Person "Ellie" Female 29)]
 [31,29]

`filter`를 이용한 필터링

주어진 목록 :

 li = [1,2,3,4,5]

filter :: (a -> Bool) -> [a] -> [a] 사용하여 술어로 목록을 필터링 할 수 있습니다.

 filter (== 1) li       -- [1]
 
 filter (even) li       -- [2,4]
 
 filter (odd) li        -- [1,3,5]
 
 -- Something slightly more complicated
 comfy i = notTooLarge && isEven
   where 
      notTooLarge = (i + 1) < 5
      isEven = even i
 
 filter comfy li        -- [2]

물론 숫자에 관한 것이 아닙니다.

 data Gender = Male | Female deriving Show
 data Person = Person String Gender Int deriving Show
 
 onlyLadies :: [Person] -> Person
 onlyLadies x = filter isFemale x
   where 
     isFemale (Person _ Female _) = True
     isFemale _ = False
 
 onlyLadies [(Person "Alex" Male 31),(Person "Ellie" Female 29)]
 -- [Person "Ellie" Female 29]

목록 압축 및 압축 해제

zip은 두 개의 목록을 취하여 해당하는 쌍의 목록을 반환합니다.

zip []     _      = []
zip _      []     = []
zip (a:as) (b:bs) = (a,b) : zip as bs

> zip [1,3,5] [2,4,6]
> [(1,2),(3,4),(5,6)]

함수로 두 개의 목록 압축하기 :

zipWith f  []     _      = []
zipWith f  _      []     = []
zipWith f  (a:as) (b:bs) = f a b : zipWith f as bs

> zipWith (+) [1,3,5] [2,4,6]
> [3,7,11]

목록 압축 풀기 :

unzip = foldr (\(a,b) ~(as,bs) -> (a:as,b:bs)) ([],[])

> unzip [(1,2),(3,4),(5,6)]
> ([1,3,5],[2,4,6])


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow