2016-05-13 80 views
0

我寫了一個代表一些計算的單子。現在,我想定義如何計算應該是sequenced。所以,我要定義>>=。但是,流量的控制迫使我把注意力集中在a的conrete類型上。我的意思是:特別是Monad。 Haskell

m >>= f = 
    a <- m 
    case a of 
     (ParticularParameterA) -> doSomething 
      .......... 

它是否正確的解決方案?我的意思是:我沒有功能編程方面的經驗,所以我不確定可以做或不做。如何做得更好?

+1

'm'應該已經有一個固定的類型,通過monad實例,所以不應該有切換需要也不可能。你的意思是你選擇/切換monad類型的構造函數嗎? – MicroVirus

+0

是的,確實如此。我編輯過。 – Gilgamesz

+0

你的編輯只是讓代碼變得荒謬,在do-block/list理解之外有一個'<-'。 – MicroVirus

回答

1

這可能是您的情況屬於簡單的圖案,其中你的單子,如果下面的形式:

newtype MyMonad a = MyMonad { run :: State -> (a, State) } 

其中State是你設計自己的數據類型。該點你可能有一個功能:

run :: MyMonad a -> State -> (a, State) 

,你可能需要使用此功能在實現時(>> =):

m >>= f = MyMonad(\state -> let (x, newState) = run m state in 
           case x of 
           (ParticularParameterA) -> doSomething 
           .......... 

現在,如果你f::a -> MyMonad b功能\state -> ...必須返回一個(b, State),所以你可能想在你的代碼中使用run (f x) newState

如果你的單子類型的形式爲:

newtype MyMonad a = MyMonad { run :: State -> Maybe (a, State) } 
newtype MyMonad a = MyMonad { run :: State -> Either String (a, State) } 

那麼你還是使用run功能,例如

m >>= f = MyMonad (\state -> case run m state of 
           Just (x, newState) -> run (f x) newState 
           Nothing    -> Nothing) 
2

case聲明和語法錯誤,儘管如此,這個定義實際上是明顯無意義的,因爲在do-block中的綁定被轉換爲使用>>=。所以你現有的代碼已經定義了m >>= f = m >>= \a -> ...,這是一個無限循環和一個空間泄漏。