编译说
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) 我在编写符号时混淆纯函数和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函数结合起来的优雅方法是什么?
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。应用h到w很容易,让我们只说这是 …
在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 中的等价形式,结果是一样的,这意味着我在这里误解了一些基本的东西。
我正在编写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
可以重新绑定(>> =)并使用显式字典传递返回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) 我有以下用于操纵机器人的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
因此,我正在编写自己的解析器,该解析器快要完成了,但是我一直陷入函数返回的困境。我的返回值是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”)。通常情况下,我只是将其“拆包”,但是,如何在一个包装箱内进行呢?
谢谢你的帮助
我有一个工作程序
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)
?
我正在寻找重复字符串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)
但我仍然不明白它是如何工作的。谁能解释这种行为?
do-notation ×10
haskell ×10
monads ×8
coding-style ×1
equivalence ×1
if-statement ×1
io ×1
io-monad ×1
list ×1
parsing ×1
typeclass ×1
types ×1