虽然在Haskell循环条件
我在这里有一个小哈斯克尔情况。我试图用monad编写两个函数。 只要条件对于函数的输入/输出为真,首先应该遍历一个函数。第二个应该使用第一个数字作为输入,并将其写入输出,直到输入空格。虽然在Haskell循环条件
我坚持这一点,任何帮助?
module Test where
while :: (a -> Bool) -> (a -> IO a) -> a -> IO a
while praed funktion x = do
f <- praed (funktion x)
if f == True then do
y <- funktion x
while praed funktion y
else return x
power2 :: IO()
power2 = do putStr (Please enter a number.")
i <- getChar
while praed funktion
where praed x = if x /= ' ' then False else True
funktion = i
import Control.Monad
while :: (a -> Bool) -> (a -> IO a) -> a -> IO a
while praed funktion x
| praed x = do
y <- funktion x
while praed funktion y
| otherwise = return x
power2 :: IO()
power2 = do
putStr "Please enter a number."
i <- getChar
let praed x = x /= ' '
let f x = do
putChar x
getChar
while praed f '?'
return()
一些注意事项:
- 使用
if x then True else False
是多余的,它相当于只是x
。 - 同样
if x == True ...
是多余的,相当于if x ...
。 -
您需要区分
IO
操作及其结果。例如,如果哟做do i <- getChar ...
然后...
i
代表的动作,角色,所以i :: Char
的结果。但是getChar :: IO Char
是行动本身。您可以将其视为执行时返回Char
的配方。你可以将配方传递给函数等,只有在某个地方执行时才会执行。 -
你的
while
调用了funktion
两次,这可能不是你想要的 - 它会读一个字符两次,检查第一个并返回第二个。请记住,您的funktion
是一个动作,因此每次您“调用”该动作时(例如通过使用do
表示法中的<- funktion ...
),该动作会再次运行。所以它应该是像do y <- funktion x f <- praed y -- ...
(我的代码有所不同,它会检查传递给它的参数。)
真棒,谢谢。我明白你是如何做到这一点的,这很有道理。我仍然不确定到底发生了什么,tho。确切地说,在哪个点上检查条件是否正确? – Chris
@Chris在做任何其他事情之前,它会检查条件是否适用于其类型为“a”的参数,就像功能语言中的while语句一样。这是通过使用[guard](http://learnyouahaskell.com/syntax-in-functions#guards-guards)来完成的,通常比'if/then/else'更可取。行'| praed x = do ...'说,如果'praed x'是真的,继续..._。下一行'|否则= ...'涵盖所有其他情况(因为'否则'只是'真'的同义词,否则'总是满足的条件]。 –
对于纯版本:
{-# LANGUAGE BangPatterns #-}
while :: (a -> Bool) -> (a -> a) -> a -> a
while p f = go where go !x = if p x then go (f x) else x
test1 :: Int
test1 = while (< 1000) (* 2) 2
-- test1 => 1024
for monadic:
import Control.Monad
whileM :: (Monad m, MonadPlus f) => (a -> m Bool) -> m a -> m (f a)
whileM p f = go where
go = do
x <- f
r <- p x
if r then (return x `mplus`) `liftM` go else return mzero
test2 :: IO [String]
test2 = whileM (return . (/= "quit")) getLine
-- *Main> test2
-- quit
-- []
-- *Main> test2
-- 1
-- 2
-- 3
-- quit
-- ["1","2","3"]
power2 :: IO (Maybe Char)
power2 = whileM (return . (/= 'q')) getChar
-- *Main> power2
-- q
-- Nothing
-- *Main> power2
-- 1
-- 2
-- 3
-- q
-- Just '\n'
see al所以:
http://hackage.haskell.org/package/monad-loops,http://hackage.haskell.org/package/loop-while,http://hackage.haskell.org/package/control-monad-loop。
http://www.haskellforall.com/2012/01/haskell-for-c-programmers-for-loops.html
另一个纯版本) 'while p = until(not。p)' – wowofbob
那么,哪一个是你的问题呢?你卡在哪里,什么不行? – leftaroundabout
这两个函数都没有编译,我敢肯定,他们不会做我希望他们做的事情。我只是不知道如何在工作版本中编写它。我基本上试图让一个while循环处理一个条件。因此,例如, '而奇数(方格3)' 应该测试方格3是否是奇数,然后使用方格3 = 9的结果并且在奇数(方格9)的情况下使用 '等等。 从技术上讲,它不应该需要一个x,它应该只与 ''同时条件函数' – Chris