1

(IO としましょう) モナドを分解できない理由がわかりません。のようにIO a -> a

私の質問は、 happstack を使用していて、 によって返されるものを取得したいときに発生しTextましServerPart (Maybe Text)(optional $ lookText "domain")IOそれから、モナドはエスケープできないということ を読んだことを思い出しました。

私はunsafePerformIOそれが悪い理由について読んだことがありますが、それらの理由のどれも私の質問に答えていないようです.

4

2 に答える 2

10

Monadから逃れることはできますか?

はい。これは、、、Monad、 などの多くの s で非常に簡単です。エスケープされる最も一般的なs の 1 つは、関数:です。関数を値に変換することができなければ、Haskell はあまり役に立ちません。MaybeEither aStateIdentityMonadMonad(->) r

IOから逃れることができますか?

残念ながらそうです。初心者にとっては、ググって、 を使用することから技術的に逃れることができることを確認しなければ、はるかに良いIOでしょunsafePerformIOう。通常のコードで使用することを意図したものではなく、本当に必要なときにランタイム システムへのバックドアとして使用します。主に、 などの低レベル ライブラリの実装に使用されますが、外部共有ライブラリ (DLL) とのインターフェイスにも使用されます。 そのようなコードを書いていない場合は、使用しないでください。そうしないと、型システムをバイパスするため、推論や保守が困難なコードになってしまいます。VectorunsafePerformIO

どうすれば他Monadのものから逃れることができますか?

MonadからまでさまざまですMonadが、ほとんどのモナド変換子にはrun-eval-またはexec-メソッドがあります。

> :m Control.Monad.State
> runState (modify (*10) >> get >>= return . show) 1
("10", 10)
> :type runState (modify (*10) >> get >>= return . show) 1
runState (modify (*10) >> get >>= return . show) 1 :: (String, Int)
> evalState (modify (*10) >> get >>= return . show) 1
"10"
> execState (modify (*10) >> get >>= return . show) 1
10

にはMaybe Monad、それから逃れる方法がいくつかあります。

> :m Data.Maybe
> maybe "nada" show (Just 2)
"2"
> maybe "nada" show Nothing
"nada"
> fromMaybe 1 (Just 10)
10
> fromMaybe 1 Nothing
1
> fromJust (Just 1)
1
> fromJust Nothing
*** Exception: Maybe.fromJust: Nothing

ご覧のとおり、すべてが安全に使用できるわけではありません。

これは Happstack とどのような関係がありますか?

わかりません。Happstack を十分に使用したことがありません。ただし、簡単に検索すると、Web サイトでこの例にたどり着きました。これは、あなたの状況にかなり当てはまるようです。

于 2014-05-28T02:55:34.087 に答える
5

あなたの質問に別の質問で答えさせてください: なぜモナドから物事を引き出すことができると思いますか?

data Dud a = Dud

instance Functor Dud where
  fmap _ _ = Dud

instance Monad Dud where
  return _  = Dud
  Dud >>= _ = Dud

より直接的には、タイプMonad作成して組み合わせることができます。この形式には多くのタイプが存在し、実際には何も抽出できない場合があります。

より意味のある、直接的な例は list モナドです。

returnList :: a -> [a]
returnList a = [a]

bindList :: [a] -> (a -> [b]) -> [b]
bindList as f = concat (map f as)

リストには明らかに何かが含まれている可能性がありますが、含まれていない可能性もあります。機能はありません

[a] -> a

渡されたときにエラーをスローしません[]


通常、モナドから「何かを取り出したい」理由は、次のような操作があるからです。

f :: a -> b

そして次のようなモナド値

m :: [a]

aそれをモナドから引き出して、関数に適用したいとします。上で述べたように、それができると信じる理由はありません。

代わりに、逆のことを行います。関数を型に取り込みます。

map f :: [a] -> [b]
于 2014-05-28T03:01:22.207 に答える