2013-10-17 45 views
0

我要一個一元值轉換成其他的單子類的一元價值。哈斯克爾從IO皈依米

可以說我有一個實例聲明:

instance ClassM TypeT where 
     funcX = abc >>= \x -> return (x) 

ClassM:是定義一個自己的單子類
TypeT:是自己定義的類型/有單子實例數據執行
ABC:是類型IO一個

如何轉換ABC :: IO的一元值的
到的classM米一個monadic值=>毫安
又名M1一個 - >米2(其中,m1是不平方米) (例如:IO 5 - >僅有5)

我的實現funcX顯然是不正確的。如果可能的話,那麼正確的實施應該是什麼?

謝謝你的時間和幫助。

+1

對'm a'到'IO a',看看'MonadIO'中的'liftIO'。更一般地說,從'MonadTrans'提升''。否則,也許你會對'mmorph'包感興趣。 – thoferon

+1

你可能意識到了這一點,但只是說:'\ X - >回x'簡直是'return',並通過法律的單子'V >> = return'必須是'v'再次,始終。所以目前你只有'funcX = abc'。 – leftaroundabout

+1

這是不可能通過設計。你不能從一個值解開IO。它永遠像鑽石一樣。或許,如果你告訴我們你想解決什麼問題,我們就可以幫你。 –

回答

-1

Monad的「類」它不是來自對象的「類」。

你問Comonads - >Monad轉型:Comonad package

convert :: (Comonad w, Monad m) => w a -> m a 
convert = return . extract 

在任何情況下,你不能從IO

comonad

你可以使用使用unsafePerormIO

+2

在'unsafePerformIO':你可能* *,但在大多數情況下,你不應該。 – duplode

5

Monad的一些兩輪牛車類代表所有單子的事物---它是一個形容詞而不是名詞。如果您想對特定單子轉換成一個值,它是通用在所有的單子那種看起來像這些

Monad m => IO a  -> m a 
Monad m => Maybe a -> m a 
Monad m => [a]  -> m a 
Monad m => Either e a -> m a 

之一,而且一般是不可能的,雖然one type of very special monads具有這種性質。

你可以做的另一件事是在底部使用Monad變壓器,IO。這意味着你將另一個monad層疊在「IO之上」。這讓你有一般操作

lift :: MonadTrans t => m a -> t m a  -- notice that t takes two parameters 
lift :: IO a -> MyTransformer IO a  -- specializing the generic function 

,並根據什麼MyTransformer是,具體操作

runMyTransformer :: MyTransformer m a -> m a 
runMyTransformer :: MyTransformer IO a -> IO a -- specialized 

例如,最簡單的很是MonadTransIdT

newtype IdT m a = IdT { runIdT :: m a } deriving Functor 

instance Monad m => Monad (IdT m) where 
    return a = IdT (return a) 
    IdT ma >>= f = IdT (ma >>= runIdT . f) 

instance MonadTrans IdT where 
    lift ma = IdT ma 

給我們操作

lift :: IO a -> IdT IO a 
runIdT :: IdT IO a -> IO a 

這只是彼此的反轉,在這種情況下。一般來說,行爲可能更復雜。