2013-11-04 7 views
21

Exercise 5 of the Haskell Typeclassopedia Section 3.2 2つのファンクタの組成物はまた、関数子である2つのFunctorを構成することは何を意味しますか?

文で証明または反例を要求します。種類は私の知る限りとして一致しないため、私はこれがFunctor 2つの別々のインスタンスで定義されたfmap方法を構成話していたことを最初に思ったが、それは本当に意味がない

伝えることができます。 ff'の2種類のタイプの場合、fmapのタイプはfmap :: (a -> b) -> f a -> f bfmap :: (a -> b) -> f' a -> f' bとなり、実際は構成可能ではありません。では、2つを構成することは何を意味しますかFunctors? (これはfmap = xxある)関数に型への型レベル・マッピング・タイプの一方(これはinstance Functor x wherexで)、用語レベルマッピング関数のいずれか

+2

ghciで実際にfmapを作成しようとしましたか?すなわち ':t fmap。 fmap' – Squidly

+0

@MrBonesチップをありがとう! ghciアクセス権を持たない人のために、出力は '::(Functor f1、Functor f)=>(a - > b) - > f(f1 a) - > f(f1 b)' – akbiggs

答えて

24

Functorは、2つのマッピングを与えます。用語レベルのマッピングを作成することを検討していますが、タイプレベルのマッピングを作成することを検討する必要があります。例えば、あなたが

instance (Functor f, Functor g) => Functor (Compose f g) 

を書くことができます

data Compose f g x = Compose (f (g x)) 

を与えられましたか?そうでない場合は、どうしてですか?あなたが別の関数の中で一つの関数を置くとき

+1

です。ソリューションを譲り渡さずにTypeclassopediaのエクササイズを説明する優れた答えです。 – Will

11

2つの機能の組成はこれは2つの機能roundsqrtの組成物である、そのような

round (sqrt 23) 

として、です。次のような

Just [3, 5, 6, 2] 

一覧はファンクタである、別のファンクタ内の1つのファンクタを入れて、そうかもしれないとき同様に、2つのファンクタの組成物です。 fmapが上記の値に何をするべきかを理解しようとすると、彼らの構成がファンクターである理由についての直感を得ることができます。もちろん、内側のファンクタの内容をマップする必要があります。

12

それは本当にファンクタF: C -> DカテゴリD内のオブジェクトと射のカテゴリCからオブジェクトや射にオブジェクト(値)と射(機能)を取り、ここにカテゴリの解釈について考えることができます。

第ファンクタG : D -> EためファンクタG . F : C -> Eの組成物は、わずかGfmap変換のドメインであることがFfmap変換の終域を取っています。ハスケルではこれはちょっと新しいタイプのアンラップで達成されます。

import Data.Functor 

newtype Comp f g a = Comp { unComp :: f (g a) } 

compose :: f (g a) -> Comp f g a 
compose = Comp 

decompose :: Comp f g a -> f (g a) 
decompose = unComp 

instance (Functor f, Functor g) => Functor (Comp f g) where 
    fmap f = compose . fmap (fmap f) . decompose 
+2

ちょっと!スポイラーはありません! = P –

+1

'f 'は' functor'と 'function'を同時に参照していますか?答えが "はい"だった場合、なぜ 'Functor f'の型制約が' fmap f'の 'f'に当てはまりませんか? – Kamel

12

はこれが何を話していることは型コンストラクタ[]Maybefmapのような機能のない構図のようなの組成物です。したがって、たとえば、[]Maybeを構成する2つの方法があります。

newtype ListOfMabye a = ListOfMaybe [Maybe a] 
newtype MaybeOfList a = MaybeOfList (Maybe [a]) 

は2 Functorsの組成はFunctorであることを声明では、これらのタイプのFunctorインスタンスを書くの定型方法があることを意味します

:実際には
instance Functor ListOfMaybe where 
    fmap f (ListOfMaybe x) = ListOfMaybe (fmap (fmap f) x) 

instance Functor MaybeOfList where 
    fmap f (MaybeOfList x) = MaybeOfList (fmap (fmap f) x) 

は、Haskellのプラットフォームはあなたに、この「無料で」いComposeタイプを与えるモジュールData.Functor.Composeが付属しています

import Data.Functor.Compose 

newtype Compose f g a = Compose { getCompose :: f (g a) } 

instance (Functor f, Functor g) => Functor (Compose f g) where 
    fmap f (Compose x) = Compose (fmap (fmap f) x) 

ComposeGeneralizedNewtypeDeriving拡張に特に有用である2つのApplicative Sの組成物はまたApplicativeある

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

newtype ListOfMaybe a = ListOfMaybe (Compose [] Maybe a) 
    -- Now we can derive Functor and Applicative instances based on those of Compose 
    deriving (Functor, Applicative) 

留意されたいです。したがって、[]MaybeApplicativeであるので、Compose [] MaybeListOfMaybeです。あなたがモナドの完全な力を必要としない場合のためのモナド変圧器の代替案として、最近ではますます一般的になりつつあります。

+0

確かにここではすべての答えの中で最も有用です。さらに私に聞かせてください:fmap f(Compose x)を書くとき、xの型は何ですか?私はそれがf g aだと言っていますが、計算(fmap(fmap f)x)を視覚化するのにはまだ苦労しています。 getComposeについてもっと頑張ってください。 NB:文字「f」は、ここでは2つの異なる役割で使用されていることを理解しています。 –

関連する問題