标签: do-notation

Haskell IF Else

input <- readLn
 if (input == 0)
 then 
  putStr  "0" 
 else if (input ==1)
then 
  putStr  "1" 
else if (input ==2)
Run Code Online (Sandbox Code Playgroud)

在这种情况下如何使用多个putStr在一个thenelse if

当我尝试收到错误

Type error in application
*** Expression     : putStr "0" putStr "0"
*** Term           : putStr
*** Type           : String -> IO ()
*** Does not match : a -> b -> c -> d
Run Code Online (Sandbox Code Playgroud)

monads haskell if-statement do-notation

4
推荐指数
3
解决办法
5086
查看次数

这个Haskell let-in缩进有什么问题?

在下面的Haskell代码中,我得到一个错误"输入中的解析错误".从我读过的,我用过的缩进应该没问题.事实上,我在代码的其他地方使用'let'和'in'进行了类似的缩进('let'与'in'对齐).我打破了什么规则会导致这个'in'出现问题?如果我在'in'前面添加一个空格(使其比'let'更加一个空格),它编译得很好.

runTests :: IO ()
runTests = do
             let results = fmap testLispExpr testLispText
                 resultStrings = fmap show results
                 putSeq (x:xs) = do putStrLn x
                                    putSeq xs
                 putSeq [] = return ()
             in putSeq resultStrings
Run Code Online (Sandbox Code Playgroud)

所有帮助表示赞赏.提前致谢.

syntax haskell indentation let do-notation

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

这种语法是否与表示法一样具有表现力?

do标记允许我们表达单子代码没有压倒嵌套,使

main = getLine >>= \ a -> 
       getLine >>= \ b ->
       putStrLn (a ++ b)
Run Code Online (Sandbox Code Playgroud)

可以表达为

main = do
  a <- getLine
  b <- getLine
  putStrLn (a ++ b)
Run Code Online (Sandbox Code Playgroud)

但是,假设语法允许... #expression ...代表do { x <- expression; return (... x ...) }.例如,foo = f a #(b 1) c将被贬低为:foo = do { x <- b 1; return (f a x c) }.上面的代码可以表示为:

main = let a = #getLine in
       let …
Run Code Online (Sandbox Code Playgroud)

syntax haskell do-notation

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

如何在Haskell中使用IO Double作为常规Double

我必须遵循代码

isInCircle::Double->Double->Bool
isInCircle p1 p2 = sqrt((p1*p1)+(p2*p2)) <= 1
Run Code Online (Sandbox Code Playgroud)

当我打电话的时候

isInCircle (random :: Double) (random :: Double)
Run Code Online (Sandbox Code Playgroud)

我收到这个错误

* Couldn't match expected type `Double' with actual type `g0 -> (a0, g0)'
Run Code Online (Sandbox Code Playgroud)

如果我将isInCircle函数的参数更改为IO Double我得到错误sqrt并添加...

你能帮助我吗?我的代码:

import System.Random 
main :: IO () 
main = do 
    if isInCircle (random :: Double) (random :: Double) 
    then print "True" 
    else print "False" 

isInCircle::Double->Double->Bool 
isInCircle p1 p2 = sqrt((p1*p1)+(p2*p2)) <= 1
Run Code Online (Sandbox Code Playgroud)

random io monads haskell do-notation

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

为什么类型在do块的下一行而不是在同一行匹配?

我正在从用户必须输入的输入中读取几行内容:

main :: IO ()
main = do
  let size = 3
  arr <- replicateM size getLine
  let pairs = map parsePair arr
  print pairs
Run Code Online (Sandbox Code Playgroud)

为什么我可以map parsePair arr在单独的行上做而不是在同一行上做,像这样:

arr <- map parsePair (replicateM size getLine)
Run Code Online (Sandbox Code Playgroud)

这样做,我得到了错误?:

• Couldn't match type ‘[]’ with ‘IO’
  Expected type: IO [Int]
    Actual type: [[Int]]
Run Code Online (Sandbox Code Playgroud)

为了给您更多细节,这里是parsePair

parsePair string = map parseInt $ words string

parseInt :: String -> Int
parseInt s = read s :: Int
Run Code Online (Sandbox Code Playgroud)

io monads haskell do-notation io-monad

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

Haskell 如何在这个 do 块中“脱糖” getline ?

我读过一些关于 Haskell 的书,但还没有编写太多代码,而且我对 Haskell 在某种情况下所做的事情有点困惑。假设我正在使用getLine,以便用户可以按一个键继续,但我真的不想以任何有意义的方式解释该人的输入。我相信这是执行此操作的有效方法:

main = do
    _ <- getLine
    putStrLn "foo"
Run Code Online (Sandbox Code Playgroud)

我了解这是在做什么的基本要点。getLine返回一个IO String,并putStrLn接受一个String并返回IO (),所以如果我理论上想打印用户在控制台中输入的内容,我基本上会使用>>=类中的运算符Monad。就我而言,我相信我的代码相当于getLine >> putStrLn "foo"因为我放弃了 的返回值getLine

但是,如果我这样做怎么办?

main = do
    let _ = getLine
    putStrLn "foo"
Run Code Online (Sandbox Code Playgroud)

在本例中,我们正在设置一种 lambda 来处理需要 的东西IO String,对吗?我可以编写一个printIOString函数来打印用户的输入,这样效果就很好。然而,当我实际上没有使用它时IO String,程序的行为很奇怪......getLine甚至不提示我输入;程序只是打印出来"foo"

我不太确定这里的“脱糖”语法是什么,或者这是否会揭示 Haskell 在幕后所做的事情。

monads haskell do-notation

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

哈斯克尔:'做[1,2,3]; ["你好"]'行为澄清

所以我试图准确理解Haskell do符号是如何工作的.据我所知,它与monad一起使用,它基本上扩展(因为它实际上是语法糖)到与bind(>>=)或then(>>)连接的匿名函数,如下所示https://en.wikibooks.org/wiki/Haskell/Syntactic_sugar #Do_notation.

但是我的问题是为什么以下命令

Prelude> do [1, 2, 3]; "hello"
Run Code Online (Sandbox Code Playgroud)

回报

"hellohellohello"
Run Code Online (Sandbox Code Playgroud)

我知道数组实际上是monad(并且这些字符串是字符数组)但是我没有看到它如何导致上面的行为.

monads haskell do-notation

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

如何在 May 和 IO 中使用 Do 表示法

我正在努力掌握do notationHaskell 中的内容。

我可以将它与 Maybe 一起使用,然后打印结果。像这样:

maybeAdd :: Maybe Integer
maybeAdd = do one <- maybe1
              two <- maybe2
              three <- maybe3
              return (one + two + three)

main :: IO ()
main = putStr (show $ fromMaybe 0 maybeAdd)
Run Code Online (Sandbox Code Playgroud)

但是,我没有使用单独的函数,而是尝试在主函数中使用带有 Maybe 的 do 表示法。但我没有任何运气。我尝试的各种尝试包括:

main :: IO ()
main = do one <- maybe1
          two <- maybe2
          three <- maybe3
          putStr (show $ fromMaybe 0 $ return (one + two + three))
Run Code Online (Sandbox Code Playgroud)
main :: IO ()
main …
Run Code Online (Sandbox Code Playgroud)

monads haskell do-notation

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

IO 是 Functor 的一个实例,因为它首先是一个 Monad 吗?

LYAH我了解到这个do符号只是monadic风格的语法糖;从维基书中我读到的或多或少是一样的;所以我的理解是,do如果没有Monad实例,就不可能有任何符号。

然而,我阅读FunctorIO类型 ctor实例的这个定义。

instance Functor IO where  
    fmap f action = do  
        result <- action  
        return (f result)  
Run Code Online (Sandbox Code Playgroud)

这只是以下内容的语法糖,不是吗?

instance Functor IO where  
    fmap f action = action >>= return . f  
Run Code Online (Sandbox Code Playgroud)

这意味着下面的假设IOMonadfirst 的实例;这与每个Monad都是一个Functor而不是相反的事实背道而驰。

事实上,我已经意识到 aMonad是“多于” an Applicative,而后者又是“多于” a Functor,这与对其实例Applicative强制执行Functor约束Monad的定义(以及理想情况下的定义要求其实例是Applicatives,因为如果它不是就不要让它成为Monad …

monads haskell functor do-notation io-monad

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

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

阅读这篇博文 – 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
查看次数