Haskell 학습 - functor

6076 단어
Haskell 학습 -functor

Functor


functor는 맵 조작을 실행할 수 있는 대상입니다. functor는 의미를 부가한 표현식처럼 상자로 비유할 수 있습니다.functor의 정의는 다음과 같이 이해할 수 있다. a가 b에 비치는 함수와 a가 담긴 상자를 제시하면 b가 담긴 상자를 되돌려준다.fmap은 function과 functor를 받아들이는 함수로 볼 수 있으며, function을 functor의 모든 요소에 적용합니다.
-- Functor 
class Functor f where
    fmap :: (a -> b) -> f a -> f b

맵 오버(map over)를 수행할 수 있는 유형은 Functor 기본 클래스를 계승하고 fmap 함수를 실현해야 합니다.몇 가지 기본 Functor 형태를 살펴보겠습니다.
  • 목록list, 매우 이해합니다. 조작 목록은 우리가 일반적으로 맵 함수를 사용하는데 이것은 사실 fmap이 목록에 대한 구체적인 실례입니다.list에서 그것들은 등가입니다..
    --  functor  :
    instance Functor [] where
        fmap = map
    
    --  
    fmap (*2) [1,2,3]
    > [2,4,6]
  • Maybe, 이것은haskell에서 매우 광범위하게 사용되는 데이터 형식으로 Just 값과 Nothing 두 가지 상황이 있는데 각각 성공과 실패를 나타내는 데 쓰인다
    -- Maybe   functor  :
    instance Functor Maybe where
        fmap f (Just x) = Just (f x)
        fmap f Nothing = Nothing
    
    --  
    fmap (*2) (Just 1)
    > Just 2
    
    fmap (*2) (Nothing)
    > Nothing
  • IO, 입력과 출력, 예를 들어 키보드 입력 읽기, 문자열 인쇄 등
    -- IO   Functor  
    instance Functor IO where
        fmap f action = do
              result  "hello! jeff"

  • Functor의 (->) r 형태


    (->)r는 함수 결합, 즉 (.)
    --  ,  (->) r   Functor    
    instance Functor ((->) r) where
        fmap f g = (\x -> f (g x))
    
    instance Functor ((->) r) where
        fmap = (.)
    
    --  
    fmap (*3) (+100) 1
    > 303
    
    (*3) . (+100)  $ 1
    > 303

    functor law


    만약 어떤 유형이 이 두 법칙을 준수한다면, 그것은 다른 Functor와 매핑에 있어서 같은 성질을 가진다.
  • fmap id = id 만약에 우리가 functor에 맵 id를 한다면 새로운 functor는 원래와 같아야 한다
    fmap id (Just 3) 
    > Just 3
    id (Just 3) 
    > Just 3
  • fmap (f . g) = fmap f . fmap g, 즉functor는 함수 결합에 응용할 수 있는..

  • Applicative Functor


      Applicative Functor가 필요한 이유, 어떤 상황에서 사용해야 하는지.Functor 정의에서 알 수 있듯이 fmap 함수는 한 개의 상자만 비추지만, 두 개의 세 개, 심지어 더 많은 상자를 비추어야 한다면?아니면 반환값이 함수인 상자를 처리해야 하나요?이것이 바로 Applicative Functor가 처리해야 할 상황이다.   Applicative Functor는 Functor의 증가판으로 볼 수 있으며, 정의에서 알 수 있듯이 주로pure와 두 함수를 포함한다.
    -- Applicative Functor  
    class (Functor f) => Applicative f where
        pure :: a -> f a
        () :: f (a -> b) -> f a -> f b
  • pure::a->fa는 기본context(의미)에 기본값을 두는 것을 의미합니다.예를 들어 list라면 [], Maybe라면 Just 값/Nothing..
  • () 함수를 장착한functor와 다른functor를 받아들인다. 이것은 fmap과 매우 유사하다. 이것은 마치 강화판의 fmap과 같다.응용 프로그램 스타일로 응용 프로그램 functors를 사용합니다.Pure f x y 같은...이 함수는 임의로 많은 매개 변수를 먹을 수 있다
    --  fmap ,  a -> b   f  
    () :: f (a -> b) -> f a -> f b
    fmap :: (a -> b) -> f a -> f b
    
    --   , 
    pure (+)  Just 3  Just 5 
    (pure (+)  Just 3)  Just 5。
  • () 는 applicative functor에서 또 다른 자주 사용하는 기호로 사실은 접두사 버전의 fmap이다.fmap과 결합하여 applicative functor를 쓰는 것이 더 편리하기 때문에..
    () :: (Functor f) => (a -> b) -> f a -> f b
    f  x = fmap f x
    --  
    pure f  x = fmap f x

  • 이어서 기본 applicative functor 몇 개를 보십시오. 응용 프로그램을 계승하려면 pure와 () 함수를 실현해야 합니다.
  • Maybe 타입
    -- Maybe   Applicative  :
    instance Applicative Maybe where
        pure = Just
        Nothing  _ = Nothing
        (Just f)  something = fmap f something
    
    --  
    pure (+3)  Just 9
    > Just 12
    
    pure (+)  Just 3  Just 5
    > Just 8
  • 목록list도 applicativefunctor로 정의에서 알 수 있듯이list를 사용하는 응용 프로그램 스타일은listcomprehension의 기능을 완전히 실현할 수 있다.그래서 응용 프로그램 스타일은list에 있어서 어떤 유형의listcomprehension을 대체하는 좋은 방식이다..
    -- list  
    instance Applicative [] where
        pure x = [x]
        fs  xs = [f x | f  [1,2]
    > [4,5,2,4]
    
    -- 
    (*)  [2,5,10]  [8,10,11] -- Applicative style
    [ x * y | x  [16,20,22,40,50,55,80,100,110]
  • IO, 아래의 IO의 실례는 getLine을 실제 세계에서 문자열을 꺼내는 상자로 볼 수 있고 applicative functor 표현식은 비교적 큰 상자를 만들 수 있다. 이 큰 상자는 두 개의 상자를 단말기에 보내 문자열을 꺼내고 그 결과를 연결해서 자신의 상자에 넣는다
    --IO   Applicative instance
    instance Applicative IO where
        pure = return
        a  b = do
            f  getLine  getLine
    aa
    bb
    > "aabb"

  • Applicative Functor의 (->) r 형태


    (->)r 형태 정의
    instance Applicative ((->) r) where
        pure x = (\_ -> x)
        f  g = \x -> f x (g x)
  • pure로 하나의 값을 applicative functor로 포장할 때, 그가 발생하는 결과는 영원히 그 값일 것이다
  • 두 개의 응용 프로그램 functor를 먹이면 새로운 응용 프로그램 functor를 만들 수 있다

  • 이어서 위의 지식을 종합하여 실제 응용 응용 응용 응용 응용 프로그램의 몇 가지 방식을 살펴보자.functor보다 applicative functor가 더 강하고 유연합니다.
    --  ,  functor, functor
    pure (\x y z -> x+ y +z)  Just 3  Just 4  Just 5
    > Just 12
    [(+3),(*2)]  [1,2]
    > [4,5,2,4]
    
    -- fmap()  , , functor
    (+)  Just 1  Just 2
    > Just 3
    (\x y z -> x + y +z)  [1,2]  [2,3]  [4,5]
    > [7,8,8,9,8,9,9,10]
    
    -- () (->) r  , , 
    (\x y z -> [x,y,z])  (3+)  (*100)  (`div`2) $ 2
    > [5,200,1]

    Applicative Functor 보조 함수

  • liftA2는 응용 프로그램의 세트 함수일 뿐이다. 물론 3개의 매개 변수의 버전인 liftA3도 있지만 liftA는 fmap과 같다
    --  applicative  
    liftA2 f a b = f  a  b
    
    --  
    liftA2 (:) (Just 3) (Just [4])
    (:)  Just 3  Just [4]
    pure (:)  Just 3  Just [4]
    
    > Just [3,4]
  • sequenceA  가 함수에 적용될 때 sequenceA는 함수가 한 무더기 들어 있는list를 받아들여 list의 함수를 돌려보낸다.같은 입력을 모두 먹이고 결과를 보려면 sequenceA가 아주 좋습니다.   I/O action에 사용할 때 sequenceA와 sequence는 등가이다.그는 일련의 I/O action을 받아들여 I/O action을 전송했다. 이 I/O action은list의 모든 I/O action을 계산하고 결과를 하나의list에 둔다
    --  sequenceA 
    sequenceA (x:xs) = (:)  x  sequenceA xs
    sequenceA = foldr (liftA2 (:)) (pure [])
    
    sequenceA [Just 3, Just 2, Just 1]
    > Just [3,2,1]
    
    --  list 
    sequenceA [[1,2,3],[4,5,6]]
    > [[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]
    
    sequenceA [(>4),(<10),odd] 7
    map (\f -> f 7) [(>4),(<10),odd]
    > [True,True,True]
    
    -- and Bool, True True
    and $ sequenceA [(>4),(<10),odd] 7
    and $ map (\f -> f 7) [(>4),(<10),odd]
    > True
  • 좋은 웹페이지 즐겨찾기