2017-06-27 5 views
2

読書実世界ハスケルTypeclassopedia 2タプル(a,b)は、ハスケルで非常に特別な役割を持つことができるという印象を受けます。2タプルの特殊な状態は何ですか?

最初に私が遭遇したのは、lookupです.2タプルのリストを辞書として使用しています。

さらに、私は((,) e)がファンクタのインスタンスであることを知りましたが(他のnタプルはありません)、上記の例では(key,value)の意味があります。

私が実際に尋ねたい最新のケースは、typeclassopediaの4.3章にあります。そこには、((,) a)Applicativeのインスタンスであり、aがモノイドであると記載されています。これは実際にそれを利用しているとき、これはいくつかの特定のタスクにとっては有用であるようです。 Applicativeのインスタンスを(a,b)にするアプリケーションとは何ですか?

+3

ああ、それは悪化する!ペアも 'Foldable'です:https://stackoverflow.com/a/36461185/126014 –

+1

2タプル自体がそれほど特別なステータスを持っているとは思いません。要点は、通常、2タプルは3タプルよりも「適用可能」であるということです。 「辞書」がある場合は、キー値のリストを取得できます.3番目の値は意味がありません。問題は、3番目の要素で何をするかです。 –

+0

はい、最初の引数が 'Monoid'インスタンスである必要があるので、' Applicative'インスタンスが何の役に立つのだろうかと思います。 – flawr

答えて

4

トリプルまたは任意のnタプルのインスタンスを書いてから私たちを妨げるものは何もありません:

instance Functor ((,,) a b) where 
    fmap f (x,y,z) = (x,y,f z) 

instance (Monoid a, Monoid b) => Applicative ((,,) a b) where 
    pure z    = (mempty,  mempty,   z) 
    (a,b,f) <*> (x,y,z) = (a `mappend` x, b `mappend` y, f z) 

ペアは、あなたが任意のn個のタプルのインスタンスを実装することができるという意味ではそのための特別ではありません。しかし、それらのインスタンスはどこかに書かれなければならないので、私たちはどこまで行くべきかという疑問を抱く。たとえば、Monoidインスタンスは5タプルまで定義されます。確かに10タプル用に記述することは可能ですが、その時点でボイラープレートコードをコピーしています。

つまり、のペアは、そのコレクションが関係を記述する自然な方法を提供するため、特別なです。一例では、用語及びその定義に関する辞書である:

dictionary :: [(String, String)] 
dictionary = 
    [("cat", "animal that likes strings; not Strings, though") 
    ,("dog", "animal that likes you; yes you") 
    ,("foo", "a strange word used by programmers in examples") 
    ] 

(すべてのペアの最初の部分は一意であるならば)、その関係を示す他の方法は

partialDictionaryEntry :: String -> String 

場合であろう我々は"cat""dog""foo"に入力ドメインを制限、または\s -> lookup s dictionaryをbとまったく同じものです

dictionaryEntry :: String -> Maybe String 

e。そして、あなたは他のn-タプルをモデル化することができるペアで:その意味で

(a,b,z) = ((a,b),z) 
(a,b,c,z) = ((a,b,c),z) = (((a,b),c),z) 

彼らがこの機能を提供し、最小のコンテナです。ペアから他のすべてのタプル型を構築できます。理論的には、Monoidインスタンスのために既に(,) (a,b)に提供されているため、Applicative ((,,) a b)インスタンスを記述する必要はありません。

つまり、なぜそれはApplicativeインスタンスを持っていますか?これは、最も簡単なWriter実装です:

log :: (Show a) => a -> (String, a) 
log x = (show x ++ "\n", x) 

fivePlusThree = (+) <$> log 3 <*> log 5 

main = do 
    let (logs, result) = fivePlusThree 
    putStrLn logs 
    print result 
3 
5 

8 

、彼らが使用するより快適なので、あなたはおそらく、Writerとそのwriterメソッドを使用しますが、これは、関数や値に情報を追加する簡単な方法を提供します厳密な変形を提供する。

関連する問題