簡體   English   中英

Haskell Monads中的`let .. in do`和`<-`表示法有什么區別?

[英]What is the difference between `let .. in do` and `<-` notation in Haskell Monads?

我正在嘗試實現一個將字符串轉換為Maybe Ints列表的函數,例如readInts "1 2 42 foo" = [Just 1,Just 2,Just 42,Nothing]

我的第一個方法是:

readInts (s::String) = do {
    ws <- words s;
    return (map (readMaybe::(String -> Maybe Int)) ws)
}

這導致以下錯誤:

lab_monad.hs:20:52:
    Couldn't match type ‘Char’ with ‘[Char]’
    Expected type: [String]
      Actual type: String
    In the second argument of ‘map’, namely ‘ws’
    In the first argument of ‘return’, namely
      ‘(map (readMaybe :: String -> Maybe Int) ws)’
Failed, modules loaded: none.

我接下來嘗試(並工作)的是:

readInts (s::String) = do {
    let ws = (words s) in do
        return (map (readMaybe::(String -> Maybe Int)) ws)
} 

我的問題是, words s顯然是[String]類型。 為什么解釋器說它是String 我對<-運算符不了解什么?

ws <- words s ,在單子列表中,不確定地將words s 一個單詞分配給ws 剩下的代碼僅使用該單詞, return函數“神奇地”將所有單詞的運算結果組合到結果列表中。

readInts s = do
   ws <- words s  -- ws represents *each* word in words s
   return (readMaybe ws)

do表示法只是使用monadic bind語法糖:

readInts s = words s >>= (\ws -> return (readMaybe ws))

在不使用Monad實例進行列表的情況下,可以使用map將相同的功能應用於每個單詞。

readInts s = map readMaybe (words s)

另一方面, let僅提供用於另一個表達式的更復雜表達式的名稱。 可以將其視為用於定義和立即應用匿名函數的語法糖。 那是,

let x = y + z in f x

相當於

(\x -> f x) (y + z)
  ^     ^      ^
  |     |      |
  |     |      RHS of let binding
  |     part after "in"
  LHS of let binding

一個let與多個綁定語句相當於嵌套let語句:

let x = y + z
    a = b + c
in x + a

相當於

let x = y + z
in let a = b + c
   in x + a

哪個討價還價

(\x -> (\a -> x + a)(b + c))(y + z)

暫無
暫無

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

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