liftM
そして友人は、コンビネーターが行うのと同じように、純粋関数を単調な設定にジャッキアップするという目的を果たしApplicative
ます。
liftM :: Monad m => (s -> t) -> m s -> m t
試したコードには2つの問題があります。1つは、かっこがないことです。
liftM sendAllTo :: IO Socket -> IO (ByteString -> SockAddr -> IO ())
それはあなたが意図したことではありません。もう一つの問題は
sendAllTo :: Socket -> ByteString -> SockAddr -> IO ()
は単調な操作であるため、持ち上げると2層のが配信されIO
ます。通常の方法は、アプリケーションの純粋なプレフィックスを括弧で囲むことです。
liftM (sendAllTo s datastring) :: IO SockAddr -> IO (IO ())
次に、を使用して引数を作成できますliftM2
。
liftM2 SockAddrInet ioport (inet_adder host) :: IO SockAddr
それはあなたに
liftM (sendAllTo s datastring) (liftM2 SockAddrInet ioport (inet_adder host))
:: IO (IO ())
これは、操作の計算方法を説明しますが、実際にはそれを呼び出さないため、現状ではまったく何も達成しません。それはあなたが必要なところです
join (liftM (sendAllTo s datastring) (liftM2 SockAddrInet ioport (inet_addr host)))
:: IO ()
または、よりコンパクトに
sendAllTo s datastring =<< liftM2 SockAddrInet ioport (inet_adder host)
プラグ。Strathclyde Haskell Enhancementは、イディオムブラケットをサポートしています。
(|f a1 .. an|) :: m t
iff :: s1 -> ... -> sn -> t
とa1 :: m s1
...。an :: m sn
_
Applicative m
これらは、liftM
家族がモナドに対して行うのと同じ仕事をしf
、純粋なn-ary関数として扱い、効果的な引数として扱いますa1
。sもそうすることができ、そうあるべきです。an
Monad
Applicative
(|SockAddrInet ioprot (inet_addr host)|) :: IO SockAddr
と
(|(sendAllTo s datastring) (|SockAddrInet ioprot (inet_addr host)|)|) :: IO (IO ())
次に、この表記により、後置を付けて、上記のような計算されたモナディック計算を呼び出すことができます@
。
(|(sendAllTo s datastring) (|SockAddrInet ioprot (inet_addr host)|) @|) :: IO ()
f
テンプレートのは全体であるように、アプリケーションの純粋なプレフィックスをまだ括弧で囲んでいることに注意してください(sendAllTo s datastring)
。表記により、任意の位置の純粋な引数を。でマーク~
できるため、これを記述できます。
(|sendAllTo ~s ~datastring (|SockAddrInet ioprot (inet_addr host)|) @|) :: IO ()
気分があなたを連れて行くなら。
暴言。効果を説明するコンテキスト(ここ)で値を説明するカーネル(ここ)として型を切り取る方法を説明するために、正しい、、、、句読点を理解liftM
することに非常に多くのエネルギーを費やしています。このアップカットが型でより明示的に行われた場合、値と計算を調整するためにプログラムで必要なノイズが少なくなるはずです。私はコンピューターがandマークがどこに行くのかを推測することをはるかに好むべきですが、現状では、Haskellタイプは文書が曖昧すぎてそれを実現できません。join
=<<
do
(|...~...@|)
()
IO
~
@