このように動作するListのMonadインスタンスを作ることは可能ですか? [Int]
: 要素を追加するモナドインスタンスをリストする
foo = do
[1]
[2]
[3]
main = print foo -- prints [1,2,3]
は、私はすべての配列が同じ型を持つ制約が必要になり、この作業を行います。
このように動作するListのMonadインスタンスを作ることは可能ですか? [Int]
: 要素を追加するモナドインスタンスをリストする
foo = do
[1]
[2]
[3]
main = print foo -- prints [1,2,3]
は、私はすべての配列が同じ型を持つ制約が必要になり、この作業を行います。
あなたはmtl
のWriter
モナドと狂気何もあなたが望む効果を得ることができます。
type AutoList a = Writer [a]()
foo :: AutoList Int
foo = do
tell [1]
tell [2]
tell [3]
toList :: AutoList a -> [a]
toList = execWriter
main = print (toList foo)
しかし、あなたはソートのためだけにリストリテラルとそれを得る-XOverloadedLists
でひどいハックを行うことができます。注意すべき点は、各ライン上に型シグネチャを与える必要があるということです。
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module AutoList where
import GHC.Exts
import Control.Applicative
import Control.Monad.Writer
newtype AutoListM a r = AutoListM (Writer [a] r) deriving (Functor, Applicative, Monad)
type AutoList a = AutoListM a()
instance IsList (AutoList a) where
type Item (AutoList a) = a
fromList = AutoListM . tell
fromListN n = AutoListM . tell . take n
toList (AutoListM w) = execWriter w
foo :: AutoList Int
foo = do
[1] :: AutoList Int
[2] :: AutoList Int
[3] :: AutoList Int
main = print (toList foo)
それがdo記法のためのモナドにする必要がありますが、型シグネチャなしでそれがでr ~()
であることを把握することはできませんAutoListM Int r
。明示的なタイプシグネチャでは、すべてを把握することができますが、これが本当に必要な解決策であるとは思えません。Writer
とtell
を使用するよりも多くの作業があります。また、あなたが本当にすべきではないものです。
意味があります。私はこれまでWriterを使ってきましたが、私はこれを再び使用します。ありがとう! –
'(>>)の型を' m a - > m a - > m a'に変更する方法はありますか? –
実際には '-XRebindableSyntax'を使ってこれを実現できますが、モナドとは関係ありません。 @カルステン、これは答えになるはずです! (実際には、 '1'と' 2'の両方を無視するというより正確です - リストの棘は無視されません!) – leftaroundabout
@VladtheImpalaリストモナドでなければなりませんか?作者のモナドは 'foo = do {tell [1]; tell [2]; tell [3]} '、execwriter foo'を実行した場合、' [1,2,3] 'が返されます。 – bheklilr