相关疑难解决方法(0)

Monads的Desugaring do-notation

当我正在学习Haskell时,我意识到do符号只是合成糖:

a = do x <- [3..4]
       [1..2]
       return (x, 42)
Run Code Online (Sandbox Code Playgroud)

翻译成

a = [3..4] >>= (\x -> [1..2] >>= (\_ -> return (x, 42)))
Run Code Online (Sandbox Code Playgroud)

我意识到我可能会使用do-notation,但我想了解翻译中发生的事情.纯粹出于教学原因,ghc/ghci有没有办法给我一个用do-notation编写的相当复杂的monad的相应绑定语句?

编辑.事实证明#haskell上的lambdabot可以做到这一点:

<Guest61347> @undo do x <- [3..4] ; [1..2] ; return (x, 42)
<lambdabot> [3 .. 4] >>= \ x -> [1 .. 2] >> return (x, 42)
Run Code Online (Sandbox Code Playgroud)

这是Undo插件的源代码.

monads haskell do-notation

24
推荐指数
1
解决办法
4447
查看次数

函数中不一致的 do 符号

为什么允许使用此功能:

-- function 1
myfunc :: String
myfunc = do
  x <- (return True)
  show x
Run Code Online (Sandbox Code Playgroud)

这不是:

-- function 2
myfunc :: String
myfunc = do
  x <- getLine
  show x
Run Code Online (Sandbox Code Playgroud)

编译错误:

Couldn't match type `[]' with `IO'
Expected type: IO Char
Actual type: String
Run Code Online (Sandbox Code Playgroud)

我明白为什么功能 2 不应该工作,但为什么功能 1 工作呢?

为什么这会起作用:

-- function 3
myfunc = do
  x <- getLine
  return (show x)
Run Code Online (Sandbox Code Playgroud)

我知道它IO String然后返回,但是为什么函数 1 也没有被迫这样做?

monads haskell type-mismatch do-notation

8
推荐指数
2
解决办法
173
查看次数

为什么haskell的绑定函数从非monadic到monadic采用函数

我对(>>=)Haskell中绑定函数的定义有一些疑问.

因为Haskell是一种纯语言,所以我们可以使用Monad来处理带副作用的操作.我认为这个策略是有点像把所有的动作可能会引起副作用另一个世界,我们可以从"纯"哈斯克尔世界虽然控制它们do>>=.

所以当我看一下>>=函数的 定义时

(>>=) :: Monad m => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)

它需要一个(a -> m b)函数,因此m a前一个动作的结果可以"解包"到非monadic a>>=.然后,该功能(a -> m b)需要a作为其输入和返回另一个单子m b作为其结果.通过绑定功能,我可以对monadic进行操作,而不会给纯haskell代码带来任何副作用.

我的问题是为什么我们使用一个(a -> m b)函数?在我看来,一个m a -> m b函数也可以做到这一点.有什么理由,还是因为它的设计是这样的?

编辑

从意见,我知道这是很难提取am a.但是,我认为我可以将monadic m a视为a副作用.

是否有可能假设函数m a -> m b …

monads haskell

4
推荐指数
1
解决办法
569
查看次数

这个技巧如何进行类型检查?

阅读这篇博文 – https://www.haskellforall.com/2021/05/the-trick-to-avoid-deeply-nested-error.html – 我意识到我不明白为什么“技巧”实际上有效这个情况:

{-# LANGUAGE NamedFieldPuns #-}

import Text.Read (readMaybe)

data Person = Person { age :: Int, alive :: Bool } deriving (Show)

example :: String -> String -> Either String Person
example ageString aliveString = do
    age <- case readMaybe ageString of
        Nothing  -> Left "Invalid age string"
        Just age -> pure age

    if age < 0
        then Left "Negative age"
        else pure ()

    alive <- case readMaybe aliveString of
        Nothing    -> Left "Invalid alive string" …
Run Code Online (Sandbox Code Playgroud)

haskell types typechecking do-notation

3
推荐指数
1
解决办法
101
查看次数