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在一个then或else 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) 在下面的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)
所有帮助表示赞赏.提前致谢.
该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) 我必须遵循代码
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) 我正在从用户必须输入的输入中读取几行内容:
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) 我读过一些关于 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 在幕后所做的事情。
所以我试图准确理解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(并且这些字符串是字符数组)但是我没有看到它如何导致上面的行为.
我正在努力掌握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) 从LYAH我了解到这个do符号只是monadic风格的语法糖;从维基书中我读到的或多或少是一样的;所以我的理解是,do如果没有Monad实例,就不可能有任何符号。
然而,我阅读Functor了IO类型 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)
这意味着下面的假设IO是Monadfirst 的实例;这与每个Monad都是一个Functor而不是相反的事实背道而驰。
事实上,我已经意识到 aMonad是“多于” an Applicative,而后者又是“多于” a Functor,这与对其实例Applicative强制执行Functor约束Monad的定义(以及理想情况下的定义要求其实例是Applicatives,因为如果它不是,就不要让它成为Monad …
阅读这篇博文 – 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) do-notation ×10
haskell ×10
monads ×7
io ×2
io-monad ×2
syntax ×2
functor ×1
if-statement ×1
indentation ×1
let ×1
random ×1
typechecking ×1
types ×1