2015-09-27 9 views
22

コンテナ(リスト、シーケンス、マップなど)のように見えるファンクタはたくさんありますが、それ以外の多くのファンクタ(状態変換器、IO、パーサなど)はありません。私はまだ少なくともFoldableまたはTraversableのインスタンスはコンテナのようには見えませんでした。存在しますか?そうでない場合、私は彼らがなぜできないのかをよりよく理解したいと思う。コンテナのように見えないFoldableまたはTraversableインスタンスはありませんか?

+8

もしあなたが[squint a bit](http://hackage.haskell.org/package/base-4.8.1.0/docs/Data-Foldable.html#v:toList)すれば、_any_'Foldable'は必然的にリストのように見える。 – leftaroundabout

+0

@leftaroundについては、それは非常に真実ではありません。なぜなら、「Foldable」は両方向に無限に広がる可能性があるからです。しかし、私は根本的な直感に興味があります。ほとんどの場合、間に何も起こらずに物を直接折りたたむことができるように思われるが、それはあまり正式ではない。 – dfeuer

+0

'data Prod1 f g a = P1(f a)(g a)のようなものはどうですか? newtype Comp f a = Comp(f(g a));データSum1 f g a = L1(f a)| R1(g a) '?これらはすべてインスタンス(Foldable f、Foldable g)=> Foldable(X f g) 'を持ちます。私はこれらの些細なことは考えていません。 (私は信じていますが、彼らはすべて法を遵守していることを確認していません)。 – user2407038

答えて

19

すべての有効なTraversable f

data Normal (s :: Nat -> *) (x :: *) where -- Normal is Girard's terminology 
    (:-) :: s n -> Vec n x -> Normal s x 

data Nat = Zero | Suc Nat 

data Vec (n :: Nat) (x :: *) where 
    Nil :: Vec Zero n 
    (:::) :: x -> Vec n x -> Vec (Suc n) x 

一部s :: Nat -> *ためNormal sと同型であるが、それはHaskellでISOを実装することで、すべての些細なことではないのです(しかし、それは完全な依存型で行く価値があります)。道徳的に、あなたが選ぶs

data {- not really -} ShapeSize (f :: * -> *) (n :: Nat) where 
    Sized :: pi (xs :: f()) -> ShapeSize f (length xs) 

及びイソ分離して再結合形状や内容の二つの方向です。物の形はちょうどfmap (const())で与えられ、重要な点はf xの形の長さはf xの長さであるということです。

ベクトルは、左から右へ1回ずつ移動する方向に移動可能です。法線は、形状(したがってサイズ)を保持し、要素のベクトルを横切ることによって正確に移動可能です。トラバーサブルであることは、有限個の要素位置を線形の順序で並べることです。通常のファンクタへの同形は、要素を線形の順序で正確に公開します。これに対応して、構造体は全て、形状とサイズのセットと、サイズよりも厳密に小さい自然数の最初のセグメントによって与えられる位置の対応する概念を持っています。

Foldableものも有限演算であり、彼らは(賢明なtoListがある)の順序で物事を保つが、それらはFunctor秒であることが保証されていないので、彼らは形状のようにさわやかな概念を持っていません。その意味では(私の同僚のAbbott、Altenkirch、Ghaniによって定義された "コンテナ"の意味)、彼らは必ずしも形状と位置の特徴付けを認めないので、容器ではありません。あなたが運が良ければ、それらのうちのいくつかはいくつかの商のための容器かもしれません。確かにFoldableは内部構造が秘密であることを意図したSetのような構造の処理を可能にするために存在し、トラバース操作によって必ずしも尊重されない要素に関する情報の順序付けに依存する。Foldableが正しく動作するかどうかは疑いがありますが、私はそのライブラリ設計の選択肢の実用的な利点については考えませんが、より明確な仕様を望むことができます。

+0

'ShapeSize'の最初の引数は、' f() 'としてのみ使用されているときに、' * - > * 'なのはなぜですか?それがハスケルへの疑似翻訳から抜け落ちた理由は?また、Haskellは、Traversable []や 'Traversable Tree'などのように、有限性についてはあまり面倒ではありません。それはどのように物事に影響を与えますか? – dfeuer

+0

(a)ShapeSizeの最初の引数はモデル化されている 'Traversable'の引数なので' * - > * 'にあります。 (b)「トラバーサブル」は、無限の構造に対する意味がない(「未定義」はナンセンスの一種である)が、それが私たちに合うときはいつでも無限型の有限断片を意味するふりをするのは一般的で避けられないハスケルの偽善であり、例えば'Eq'インスタンス。これまでにデータとコードを分離した場合、データのみが「トラバーサブル」になります。 – pigworker

+0

一方、1つの忌み嫌い(無限のトラバーサブル)は別のもの(怠惰な状態)と混ざって、無限の構造に対して完全に感知できる 'mapAccumL'と' mapAccumR'を生成します。 – dfeuer

10

まあ、universeの助けを借りて、有限状態空間上の状態変圧器のインスタンスをFoldableTraversableと書くことができます。この考え方は、関数のためにFoldableTraversableのインスタンスにほぼ似ています。Foldableの関数をどこでも実行し、Traversableのルックアップテーブルを作成します。したがって:

import Control.Monad.State 
import Data.Map 
import Data.Universe 

-- e.g. `m ~ Identity` satisfies these constraints 
instance (Finite s, Foldable m, Monad m) => Foldable (StateT s m) where 
    foldMap f m = mconcat [foldMap f (evalStateT m s) | s <- universeF] 

fromTable :: (Finite s, Ord s) => [m (a, s)] -> StateT s m a 
fromTable vs = StateT (fromList (zip universeF vs) !) 

float :: (Traversable m, Applicative f) => m (f a, s) -> f (m (a, s)) 
float = traverse (\(fa, s) -> fmap (\a -> (a, s)) fa) 

instance (Finite s, Ord s, Traversable m, Monad m) => Traversable (StateT s m) where 
    sequenceA m = fromTable <$> traverse (float . runStateT m) universeF 

これは意味があるかわかりません。もしそうなら、私はそれをパッケージに追加して嬉しいです。どう思いますか?

+0

私はあなたがコンテナを持っていると思うし、それらのインスタンスは賢明だと思います。 – dfeuer

4

私はそれが実際にFoldableまたはTraversibleだとは思わないが、MonadRandomは、無限リストのように機能するかもしれないが、折り畳み可能なものよりもコンテナのように見えないものの例である。概念的には、それは確率変数です。

関連する問題