これは 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]
ここで曖昧な点がある理由と、エラー メッセージが表示されたときに型シグネチャを追加する方法について、ここで混乱しています。誰でも説明できますか?
前もって感謝します、