我开始使用Haskell,我试图定义一个带有一个数字的阶乘函数,如果数字为负数,则不显示任何结果。像这样(只是一个例子):
*Main> factorial 8
40320
*Main> factorial (-1)
*Main>
有可能,怎么样?
感谢。
答案 0 :(得分:9)
你只能用一个函数来做这件事,而且它可能不是你想要的。函数总是必须返回某些东西,即使它只是一个表示没有有效结果的虚拟值!这很有用,因为它意味着您的函数的结果总是可以被程序的其他部分使用 - 一切都更加可组合。
通常的惯用解决方案是使用Maybe
类型,这样您就可以返回Just
结果或Nothing
:
factorial n | n < 0 = Nothing
| n < 2 = Just 1
| otherwise = ...
如果确实想要您在GHCi中的行为,您可以打印出您想要的结果,而不是直接返回它。这使您可以更好地控制输出的外观,但这意味着您将无法直接重用函数的结果。你可以这样做:
factorialPrint n | n < 0 = return () -- an IO action that does nothing
| otherwise = print (factorial n)
此函数不会生成结果,而是生成 IO操作。 GHCi然后执行此操作并且本身不打印任何内容,这意味着您必须自己打印结果。
答案 1 :(得分:2)
如果你想保持它纯净,那么你可以通过定义一个新的结果类型并定义show
来转换为空字符串(如果结果无效):
data FactResult = R Integer | Invalid
instance Show FactResult where
show (R i) = show i
show Invalid = ""
factorial n | n < 0 = Invalid
factorial n = R $ product [1..n]
答案 2 :(得分:2)
&#34;正确&#34;做这样的事情的方法是使用Maybe。
factorial n
| n < 0 = Nothing
| n == 1 = Just 1
| otherwise = fmap (*n) $ factorial (n-1)
这输出&#34;只是n!&#34;输入任何&gt; = 0和&#34;没什么&#34;否则。
如果你真的想要一个空白的回复。
maybeStr Nothing = ""
maybeStr (Just x) = show x
然后运行打印,你会说:
f = putStrLn . maybeStr . factorial
f 4 -- would print 24
f (-1) -- would print blank line
答案 3 :(得分:1)
是的,这是可能的,但我们必须略微改变阶乘函数:
fac :: Int -> IO ()
fac n
| n < 0 = return ()
| otherwise = print $ facHelp n
where
facHelp n = <your factorial function>
现在,除了标准阶乘,我们首先检查输入,如果输入小于0,我们只返回一个叫做unit的东西,这个东西什么都没有(至少可以看到)。如果输入对于阶乘有效,我们将只是正常打印。