簡體   English   中英

初體驗Monads(Haskell)

[英]First experience with monads (Haskell)

對於這個主題不清楚,我深表歉意。 我正在初學者學習Haskell 99,並且在我的67A解決方案中第一次遇到了monad的概念。 我苦苦掙扎的問題的一部分是定義一個函數stringToTree ,該函數將a(b,c)a(b,c)序列轉換為TreeBranch a (Branch b Empty Empty) (Branch c Empty Empty)

我已經嘗試了幾種有關monad的“軟”介紹,但與其他許多例子一樣都失敗了。 我希望通過了解此解決方案最終能帶領我進入室內,因此我決定在此進行嘗試。

問題

  1. 誰能簡要解釋一下解決方案中定義的函數stringToTree :: (Monad m) => String -> m (Tree Char)是什么? 為了使這個問題自成一體,我從那里復制了代碼
stringToTree :: (Monad m) => String -> m (Tree Char)
stringToTree "" = return Empty
stringToTree [x] = return $ Branch x Empty Empty
stringToTree str = tfs str >>= \ ("", t) -> return t
    where tfs a@(x:xs) | x == ',' || x == ')' = return (a, Empty)
          tfs (x:y:xs)
                | y == ',' || y == ')' = return (y:xs, Branch x Empty Empty)
                | y == '(' = do (',':xs', l) <- tfs xs
                                (')':xs'', r) <- tfs xs'
                                return $ (xs'', Branch x l r)
          tfs _ = fail "bad parse"
  1. 為什么monad在這里有用? 我希望看到單子如何在定義此功能的同時大幅度減少困難,當然只有在了解了這一點之后。

簡而言之,定義使呼叫者可以選擇要使用的單聲道。 這使我們可以自定義處理失敗的方式。 例如,我們可以使用Maybe

>>> stringToTree "" :: Maybe (Tree Char)
Just Empty
>>> stringToTree "9 +" :: Maybe (Tree Char)
Nothing

[]

>>> stringToTree "" :: [Tree Char]
[Empty]
>>> stringToTree "9 +" :: [Tree Char]
[]

該代碼本身不假設使用哪個 monad。 它僅使用>>=return ,並且fail處理遞歸調用的結果。

鍵入String -> Tree Char表示失敗根本不會發生。 每個字符串都必須產生一個有效的Tree Char值(否則我們會引發運行時錯誤,這是您在Haskell中應避免的事情)。

但是請注意,並非所有monad都提供了避免運行時錯誤的fail定義。

>>> stringToTree "" :: Either () (Tree Char)
Right Empty
>>> stringToTree "9 +" :: Either () (Tree Char)
*** Exception: bad parse

為什么monad有用? 一些更廣泛的背景。

Monad是傳統上由不同語言機制處理的幾件事的統一 其中有

  • 排序(例如在IO或狀態下)

  • 非確定性(例如清單monad)

  • 失敗和異常(例如Maybe)

  • 保存和恢復計算(將來會遇到的Cont monad)

  • 原子交易(STM monad)

  • 解析(Parsec及其親屬)

所謂“統一”,是指牛頓將地球上和天空中的事物的物理定律統一起來,或者將麥克斯韋將電磁力統一到電磁場中時所做的事情。 它是一種更深層的基礎理論,將以上所有內容作為特殊情況進行了介紹,並展示了如何沿着相同思路創造新事物。

在monad中,“ bind”函數的類型(>>=)是理論中的中心方程; 它描述了如何將計算的一個步驟以菊花鏈方式鏈接到下一個步驟。 return是原始的空步驟。 這是您在Haskell中習慣的; 一切都有某種零或空或身份值。 fail是不起作用的步驟,部分功能需要該步驟(如@chepner在其他評論中所述)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM