为了测试我在Haskell的技能,我决定实现你在Land of Lisp/Realm of Racket中找到的第一款游戏.在"猜猜我的号码"的游戏.游戏依赖于可变状态来运行,因为它经常需要更新程序的上限和下限以回归用户正在考虑的值.
它有点像这样:
> (guess)
50
> (smaller)
25
> (bigger)
37
Run Code Online (Sandbox Code Playgroud)
现在,这种事情(据我所知)在Haskell中完全不可能,从REPL中调用一些修改全局可变状态的函数,然后立即打印结果,因为它违反了不变性原则.因此,所有交互必须存在于IO和/或Statemonad中.那就是我被困住的地方.
我似乎无法将我的想法包含在IOmonad和Statemonad的组合中,所以我可以获得输入,打印结果和修改状态,所有这些都在同一个函数中.
这是我到目前为止所得到的:
type Bound = (Int, Int) -- left is the lower bound, right is the upper
initial :: Bound
initial = (1, 100)
guess :: Bound -> Int
guess (l, u) = (l + u) `div` 2
smaller :: State Bound ()
smaller = do
bd@(l, _) <- get …Run Code Online (Sandbox Code Playgroud) 我有一个数据类型,其中包含IORef作为一个重要元素.这意味着没有一种干净的方法可以使它成为show类型类的成员.这不是太糟糕,因为我print在这种类型的IO monad中有一个函数.但是在GHCi中很烦人,因为每当我返回其中一个东西时,我都会收到错误声明它无法显示.
有没有办法让IOC无论如何在IO monad中运行,使用IO动作来显示结果?如果没有,是否会对写作产生任何负面影响show a = unsafePerformIO $ print a?
以下函数f尝试Int使用IO (Maybe Int)函数两次读取两次,但在成功读取一次后执行"短路"执行Int:
readInt :: IO (Maybe Int)
f :: IO (Maybe Int)
f = do
n1 <- readInt
case n1 of
Just n' -> return (Just n')
Nothing -> do
n2 <- readInt
case n2 of
Just n' -> return (Just n')
Nothing -> return Nothing
Run Code Online (Sandbox Code Playgroud)
有没有一种很好的方法来重构这段代码?如果我将它扩展到三次尝试,这将变得非常毛茸茸......
(我的思维过程:看到这个"staircasing"告诉我,也许我应该使用Monad的情况Maybe,但由于这是已经在IO单子,我将不得不使用MaybeT(),但我只需要?一个的readInt来成功,所以Maybemonad在第一次Nothing出错的行为在这里是错误的...)
我是Haskell的新手,并且一直试图找到一种方法将多个IO污染的值传递给一个处理C库的函数.大多数人似乎在do块中使用< - 运算符,如下所示:
g x y = x ++ y
interactiveConcat1 = do {x <- getLine;
y <- getLine;
putStrLn (g x y);
return ()}
Run Code Online (Sandbox Code Playgroud)
This makes me feel like I'm doing C, except emacs can't auto-indent. I tried to write this in a more Lispy style:
interactiveConcat2 = getLine >>= (\x ->
getLine >>= (\y ->
putStrLn (g x y) >>
return () ))
Run Code Online (Sandbox Code Playgroud)
That looks like a mess, and has a string of closed parentheses you have to …
在Haskell中打印是一个纯函数; 为什么或者为什么不?我认为这不是因为它并不总是返回与纯函数应该相同的值.
我知道在IO运算符的Scalaz中有一些几乎相同的实现putStrLn :: String -> IO (,getLine :: IO String但是我的意思是Scala标准API为什么没有这样的等价物?我知道Scala不是Haskell的纯语言,并且有副作用,但我认为这种数据类型是如此描述性和有用.我不知道Try,Option还是Either会做的工作.
Haskell wiki有以下问题:
https://en.wikibooks.org/wiki/Haskell/Higher-order_functions
for :: a -> (a -> Bool) -> (a -> a) -> (a -> IO ()) -> IO ()
for i p f job = -- ???
我能够提出以下实现:
generate :: a -> (a->Bool) -> (a->a) -> [a]
generate s cnd incr = if (cnd s) then [] else [s] ++ generate (incr s) cnd incr
-- collapse :: [IO ()] -> IO ()
-- collapse (x:xs) = x ++ collapse xs
-- does not work ^^^^^^
for::a->(a->Bool)->(a->a)->(a->IO())->IO() …Run Code Online (Sandbox Code Playgroud) abc :: IO (Int)
abc = do
print "abc"
pure $ 10
xyz :: IO (Int)
xyz = undefined
main :: IO ()
main = do
x <- (((+) <$> abc <*> abc) <* xyz)
print x
Run Code Online (Sandbox Code Playgroud)
Why in the above is xyz being evaluated? I would assume due to Haskell's lazy nature it would not need to evaluate xyz (and hence not reach the undefined)?
My assumption is based on the type of <*:
Prelude> :t (<*) …Run Code Online (Sandbox Code Playgroud) 根据cats官方文档:https : //typelevel.org/cats-effect/typeclasses/liftio.html ,如果我们想把东西从IO提升到其他容器,你应该实现LiftIO trait,但示例明确运行unsafeRunXXX方法来获取出了效果,我想知道这是转型的唯一途径吗?
您好社区,感谢您的宝贵时间。
\n我有一个错误,我不确定错误是什么,但我认为问题是:\n没有从ext-1.2.4.1:Data.Text.Internal.Lazy.Text IO)到 的IO 转换器Web.Scotty.Internal.Types.ScottyT。
但我想知道为什么编译器与ext-1.2.4.1:Data.Text.Internal.Lazy.Text IO). 这就是为什么我只使用 String 并删除了所有出现的{-# LANGUAGE OverloadedStrings #-}但仍然收到错误。另一方面,这应该是IO [String],不是吗?\n正如你所提到的,我真的不知道是什么ext-1.2.4.1:Data.Text.Internal.Lazy.Text IO)。
在另一个地方,我已经liftIO成功使用了一个a -> IO String函数。我想我也以同样的方式使用它们。
我想我慢慢地感觉到了 monad 是什么,但不太确定。我真的不知道为什么我必须使用一个lift函数。
错误信息:
\n \xe2\x80\xa2 No instance for (MonadIO\n (Web.Scotty.Internal.Types.ScottyT\n text-1.2.4.1:Data.Text.Internal.Lazy.Text IO))\n arising from a use of \xe2\x80\x98liftIO\xe2\x80\x99\n \xe2\x80\xa2 In a stmt of a \'do\' block:\n paths <- liftIO $ getAllFilePaths2 path\n In the expression:\n do …Run Code Online (Sandbox Code Playgroud) io-monad ×10
haskell ×9
monads ×3
scala ×2
applicative ×1
cats-effect ×1
emacs ×1
ghci ×1
io ×1
ioref ×1
lifting ×1
maybe ×1
scala-cats ×1
scotty ×1
state-monad ×1