Hifriends
函数是否可能返回多个值(例如字符串和布尔值)?
如果是,那么我有一个名为concat的函数,它返回一个布尔值和一个字符串,但我不知道如何调用这些函数,因为我想存储它们。我写了一个非常大的代码。所以我无法发布它。enter code here
concat::(String->Int)->(IO Bool->IO String)
concat line i=do
return True line
你能帮我写一下函数签名以及如何调用这些函数吗?
我需要一个原型
谢谢
答案 0 :(得分:11)
返回多个值时,必须返回代数数据类型。关于这一点可以说很多,我会给你一些建议。
如果您的Bool
和String
在某种程度上更相关,而且它们通常会在您的代码中出现,请定义新的代数数据类型:
data Question = Question Bool String
您也可以使用访问者函数对其进行定义,该函数也会记录数据:
data Question = Question{ answered :: Bool
, text :: String }
你可以定义一个函数e。 G。用于初始化问题:
question :: String -> Question
question str = Question False (str ++ "?")
或(为了改进文档):
question :: String -> Question
question str = Question{ answered = False
, text = str ++ "?"}
然后您可以使用数据构造函数处理数据:
answer :: String -> Question -> Question
answer answ (Question False str) =
Question True (str ++ " " ++ answ ++ ".")
answer _ old = old
或使用访问器功能(两种方法的许多组合都是可能的):
answer :: String -> Question -> Question
answer answ qstn
| answered qstn = qstn
| otherwise = qstn{ answered = True
, text = text qstn ++ " " ++ answ ++ "."}
调用函数的示例:
answer "Yes it is" (question "Is this answer already too long")
如果您不想定义新的数据类型,请使用预定义的单元组。标准库中定义了许多函数,这使得使用元组更容易。但是,不要在任何地方使用元组 - 更大的代码会变得混乱(缺少文档 - 它不清楚元组代表什么数据),由于多态性,类型错误不会那么容易追踪。
一种方便使用元组的例子:
squareAndCube :: Int -> (Int, Int)
squareAndCube x = (square, square*x)
where square = x*x
sumOfSquareAndCube :: Int -> Int
sumOfSquareAndCube x = square + cube
where (square, cube) = squareAndCube x
关于这个简单问题的说法过多,但由于我提到了标准库支持作为元组的主要优点,我将给出最后一个使用Prelude的uncurry
函数的例子:
sumOfSquareAndCube :: Int -> Int
sumOfSquareAndCube x = uncurry (+) (squareAndCube x)
答案 1 :(得分:10)
是的,您可以使用名为元组的haskell结构返回多个值。
这是一个简单的例子
addAndSub :: Int -> Int -> (Int, Int)
addAndSub a b = (a + b, a - b)
然后,您可以使用fst
访问元组的第一部分,使用snd
访问第二部分。但是最好是模式匹配
use = case addAndSub 2 3 of
(i, j) -> i + j
或
let (i,j) = addAndSub 2 3
in i + j
现在假设您的函数执行了一些IO并获得了String
和Bool
,那么您的函数看起来会模糊不清
magic :: IO (String, Bool)
magic = do
string <- getString
bool <- getBool
return (string, bool)
如果您使用do
块在monad中工作,您还可以使用更漂亮的表单进行模式匹配。
foo = do
(i, j) <- magic
请注意,此必须位于执行块中。如果您返回的值m a
m
是一个monad,您可以只使用do块,例如IO
。