[the]結果をアンパックするか、それに応じてIOErrorをスローする(クリーンで簡潔な)方法は何ですか?
エラーのスローに頼らないことをお勧めします。代わりに、「エラー」を明示的に処理します。
maybeM :: Monad m => m b -> (a -> m b) -> m (Maybe a) -> m b
maybeM err f value = do
x <- value
case x of
Just y -> f y
Nothing -> err
-- This can be written simply as:
maybeM err f value = do
x <- value
maybe err f x
-- or even shorter! This is starting to look like Anthony's answer :)
maybeM err f value = value >>= maybe err f
関数の入力と型は、それ自体で語るべきです。ケースに対して実行するアクションNothing
、またはケース内の値に対して実行する関数を指定して使用しますJust
。特定の入力の場合、これは次のようになります。
maybeM (ioError $ userError "OOPS") return (return $ Just "ok")
したがって、絶対に必要な場合、「結果をアンパックするか、IOError をスローする簡潔な方法」は次のようになります。
-- compare to fromJust, a function to be avoided
fromJustIO :: IO (Maybe a) -> IO a
fromJustIO = maybeM (ioError $ userError "OOPS") return
これの型シグネチャが実質的に であることに注意してくださいMaybe a -> a
。これは の本質であり、危険信号を発するmagicMonadUnwrap :: Monad m => m a -> a
はずです。ただし、この残虐行為を簡単な方法で使用できます。
result <- fromJustIO value
繰り返しになりますが、ここで例外を使用することは強くお勧めしません。maybeM
エラーが発生した場合に実行する IO アクションを使用して提供することにより、単に爆発するよりも洗練された方法でエラーを処理してみてください。