0

これは Data.List.Class の使用法に関する質問です ( Haskell Data.List.Class と syntaxに関する以前の質問に関連しています)。

コードの関連セグメントを以下に示します。私の理解では、このクラスは Haskell リスト型への型クラス インターフェイスまたは一般化を提供しており、非常に便利です。ただし、このクラスの使用法に関するドキュメントはあまり見つかりませんでした。誰かが良いチュートリアルを知っていますか?

また、その使用方法と種類に関する技術的/具体的な質問があります。コードから、型クラスの定義では、runList と joinL は (ある意味で) 互いに反転していると思います。

-- other stuff omitted
import Data.Functor.Identity (Identity(..))

data ListItem l a =
    Nil |
    Cons { headL :: a, tailL :: l a }

Data.List.Class
-- | A class for list types. Every list has an underlying monad.
class (MonadPlus l, Monad (ItemM l)) => List l where
    type ItemM l :: * -> *
    runList :: l a -> ItemM l (ListItem l a)
    joinL :: ItemM l (l a) -> l a
    cons :: a -> l a -> l a
    cons = mplus . return

instance List [] where
    type ItemM [] = Identity
    runList [] = Identity Nil
    runList (x:xs) = Identity $ Cons x xs
    joinL = runIdentity
    cons = (:)

fromList :: List l => [a] -> l a
fromList = foldr cons mzero

まず、joinL $ runList [1, 2, 3]emacsモードに入りましたが、以下のエラーが出ました。

Couldn't match type `ItemM (ListItem [])' with `Identity'
Expected type: ItemM (ListItem []) (ListItem [] Integer)
  Actual type: ItemM [] (ListItem [] Integer)

それが言うように、期待される型と実際の型は正確には一致しません。しかし、そもそもなぜ異なるタイプが必要なのかわかりません。とは、意味やセマンティクスの点でどのようrunList :: l a -> ItemM l (ListItem l a)に異なりますか?joinL :: ItemM l (l a) -> l a

また、次のように emacs モードで fromList という非常に単純な関数を試してみましたが、次のようfromList [1,2,3]になりました。

Ambiguous type variable `l0' in the constraint:
  (List l0) arising from a use of `fromList'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: fromList [1, 2, 3]
In an equation for `it': it = fromList [1, 2, 3]

ここで曖昧な点がある理由と、エラー メッセージが表示されたときに型シグネチャを追加する方法について、ここで混乱しています。誰でも説明できますか?

前もって感謝します、

4

1 に答える 1

1

最後の質問: List 型クラスを実装するのはいくつかの型である可能性があります。後で推論されない場合は、それを指定する必要があります。たとえば、fromList [1, 2, 3] :: [Int]正常に動作します。

于 2012-08-07T13:00:43.763 に答える