标签: do-notation

Haskell - do块中的语法(使用IO)

编译说

The last statement in a 'do' construct must be an expression:
rmax <- getInteger
Run Code Online (Sandbox Code Playgroud)

尝试加载包含以下代码段的文件时:

getInteger :: IO Integer
getInteger = readLn

main :: IO ()
main = do  
    putStrLn "specify upper limit of results"  
    rmax <- getInteger
    if rmax `notElem` mot
        then do putStrLn "run again and enter a multiple of 10"
        else do print pAllSorted
Run Code Online (Sandbox Code Playgroud)

它(编译器消息)是什么意思,为什么会在这里发生?(而它不在:)

main = do   
    line <- getLine  
    if null line  
        then return ()  
        else do  
            putStrLn $ reverseWords line  
            main  

reverseWords :: …
Run Code Online (Sandbox Code Playgroud)

io haskell if-statement do-notation

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

在编号中将monadic函数与纯函数混合使用

我在编写符号时混淆纯函数和monadic函数时遇到了麻烦.我有一种感觉,我错过了一些明显的东西.

例如,假设我有这些功能

fa :: a -> IO b
fb :: b -> c
fc :: c -> IO d

z :: a -> IO c
z a = do x <- fa a
         y <- fb x
         z <- fc y
         return z
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为

y <- fb x
Run Code Online (Sandbox Code Playgroud)

在z中行,但是将纯fb函数与monadic fa和fc函数结合起来的优雅方法是什么?

haskell coding-style do-notation

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

理解简单 Reader monad 的符号:a &lt;- (*2), b &lt;- (+10), return (a+b)

instance Monad ((->) r) where  
    return x = \_ -> x  
    h >>= f = \w -> f (h w) w  

import Control.Monad.Instances  

addStuff :: Int -> Int  
addStuff = do  
    a <- (*2)  
    b <- (+10)  
    return (a+b)  
Run Code Online (Sandbox Code Playgroud)

我试图通过展开 do 符号来理解这个 monad,因为我认为 do 符号隐藏了发生的事情。

如果我理解正确,会发生以下情况:

(*2) >>= (\a -> (+10) >>= (\b -> return (a+b))) 
Run Code Online (Sandbox Code Playgroud)

现在,如果我们采用 for 的规则>>=,我们必须理解(*2)ash(\a -> (+10) >>= (\b -> return (a+b)))as f。应用hw很容易,让我们只说这是 …

monads haskell do-notation

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

需要解释基本的 do 块语法

在ghci中,我写道:

 let x = do
    i <- [1..5]
    j <- [2..4]
    return i 
Run Code Online (Sandbox Code Playgroud)

预期结果:

[1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)

实际结果:

[1,1,1,2,2,2,3,3,3,4,4,4,5,5,5]
Run Code Online (Sandbox Code Playgroud)

我不明白该输出背后的逻辑。我认为原因可能与 monad 有关,但我对函数式编程很陌生,我希望有人能解释一下。

我也试过 List-comprehension 中的等价形式,结果是一样的,这意味着我在这里误解了一些基本的东西。

monads haskell list-comprehension list do-notation

3
推荐指数
2
解决办法
114
查看次数

在Haskell中绑定与分配

我正在编写Write Yourself a Scheme教程,一个代码块让我想知道绑定和赋值之间的区别:

 parseAtom = do first <- letter <|> symbol
            rest <- many (letter <|> digit <|> symbol)
            let atom = first:rest
            return $ case atom of 
                       "#t" -> Bool True
                       "#f" -> Bool False
                       _    -> Atom atom
Run Code Online (Sandbox Code Playgroud)

为什么let atom =而不是atom <-?因此,我试过:

parseAtom = do first <- letter <|> symbol
           rest <- many (letter <|> digit <|> symbol)
           atom <- first : rest
           return $ case atom of
                "#t" -> Bool …
Run Code Online (Sandbox Code Playgroud)

monads haskell compiler-errors assignment-operator do-notation

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

Rebind用无类型类monad表示

可以重新绑定(>> =)并使用显式字典传递返回monad,如下所示:

{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RebindableSyntax #-}

module Lib where

import Prelude hiding ((>>=), return)

data MonadDict m = MonadDict {
  bind :: forall a b. m a -> (a -> m b) -> m b ,
  ret :: forall a. a -> m a }

(>>=) :: (MonadDict m -> m a) -> (a -> (MonadDict m -> m b)) -> (MonadDict m -> m b)
return :: a -> (MonadDict m -> m a)

monadDictIO …
Run Code Online (Sandbox Code Playgroud)

monads haskell typeclass do-notation

2
推荐指数
1
解决办法
128
查看次数

Haskell:了解if-else语句的表示法

我有以下用于操纵机器人的API的代码:

data Direction = Left | Right
forward    :: IO ()
blocked :: IO Bool
turn       :: Direction -> IO ()
Run Code Online (Sandbox Code Playgroud)

我正在尝试理解两个程序,它们将使机器人向前移动,除非它被障碍物挡住,在这种情况下,机器人应向正确的方向旋转。

但是,我不确定以下两个程序之间有什么区别:

-- program 1
robot = do
  detected <- blocked
  if detected 
    then turn Right
    else forward
  robot

-- program 2
robot = do
  detected <- blocked
  if detected
    then turn Right
         robot
    else forward
         robot
Run Code Online (Sandbox Code Playgroud)

该行将detected <- blocked布尔值从IO中取出。如果条件if detected为真,则机器人向右转,否则机器人向前移动。在程序1中,向右或向前移动机器人后,将再次调用功能机器人。在程序2中,在右转或前进后直接调用功能机器人。

我不确定在if-else语句之后(在程序1中)调用机器人与在程序2 中的thenand else案例中调用机器人之间有什么区别?我是否正确地说这两个程序是等效的?任何见解都表示赞赏。

monads haskell functional-programming equivalence do-notation

2
推荐指数
1
解决办法
76
查看次数

在案例块中解析

因此,我正在编写自己的解析器,该解析器快要完成了,但是我一直陷入函数返回的困境。我的返回值是case,但是在其中,case我必须进行解析,但无法使其正常工作。

parseCompontntsTile :: Tile -> Parser Tile
parseCompontntsTile (Tile pos fix wiel) = 
    do  parseWhiteSpace
        patern <- match "pos:" `mplus`     match "fixed:" `mplus` match "wheel:"
        return (case patern of
                 "pos"   -> (Tile  parsePosition  fix  wiel)
                 "fixed" -> (Tile  pos     parseFixed  wiel)
                 "wheel" -> (Tile  pos     fix    parseWiel) )
Run Code Online (Sandbox Code Playgroud)

功能parsePosition来自类型parsePosition :: Parser Coord; tile的构造函数为Coord Bool Bool

当然,这是行不通的,因为会parsePosition返回Parser Coord并且期望返回Coord(没有“ parse”)。通常情况下,我只是将其“拆包”,但是,如何在一个包装箱内进行呢?

谢谢你的帮助

monads parsing haskell functional-programming do-notation

2
推荐指数
1
解决办法
72
查看次数

Haskell中&lt;-的类型是什么?

我有一个工作程序

main = do

  inpStr <- getLine
  putStrLn ( "Hello " ++ inpStr )
Run Code Online (Sandbox Code Playgroud)

哪里

putStrLn :: String -> IO ()
Run Code Online (Sandbox Code Playgroud)

getLine :: IO String  
Run Code Online (Sandbox Code Playgroud)

由此我可以断定的类型<-

IO a -> a
Run Code Online (Sandbox Code Playgroud)

monads haskell types do-notation io-monad

2
推荐指数
1
解决办法
76
查看次数

为什么 &gt;&gt; 在 haskell 中重复右侧操作数

我正在寻找重复字符串n时间的解决方案。我duplicate n str = [1..n] >> str从这个解决方案中找到了。我想知道为什么这个方法会重复str.

我搜索了一下>>,发现了这一点:

k >> f = k >>= \_ -> f
Run Code Online (Sandbox Code Playgroud)

a >> b >> c >> d
-- is is equivalent to
do a
   b
   c
   d
Run Code Online (Sandbox Code Playgroud)

然后我试试这个

ghci> do [1..3]; "a"
"aaa"
Run Code Online (Sandbox Code Playgroud)

但我仍然不明白它是如何工作的。谁能解释这种行为?

monads haskell do-notation

2
推荐指数
1
解决办法
140
查看次数