要在WriterMonads上进行练习,我需要制作一个函数来记录其功能。我一定不能使用元组构造函数(,)。
我已经有一个日志函数,其结果类型为(String,()) 现在我需要使用它,但是结果类型为(String,Int)
但是我不知道如何将(String,())元组转换为(String,Int)
logMsg :: String -> (String,())
logMsg msg = (msg,()) -- Durch Lösung ersetzen.
logOp :: Int -> Int -> Int -> String -> (String,())
logOp v1 v2 res math = do
logMsg "The value of "
logMsg $ show v1
logMsg math
logMsg $ show v2
logMsg " is "
logMsg $ show res
logMsg ".\n"
mult :: Int -> Int -> (String,Int)
mult m1 m2 = logOp m1 m2 (m1*m2) "*"
我测试了
logOp m1 m2 (m1*m2) "*"
执行类型为(String,())的正确结果
我不知道,有什么提示吗?
答案 0 :(得分:1)
通常,在处理单子时,会使用单子函数return
和(>>=)
。您已经在(>>=)
块中隐式使用了do
。
对于mult
,您可以尝试使用do
并在其中使用return
。在这种非常特殊的情况下,您可以假设return
被定义为
return :: Int -> (String, Int)
return x = ("", x)
(通常,它是多态的:return :: a -> (String, a)
)
答案 1 :(得分:0)
我找不到不使用构造函数直接更新元组中的值的方法,因此我不得不以低效的方式编写它。但这不使用元组构造函数:
mult m1 m2 = head $ zip [fst $ logOp m1 m2 (m1*m2) "*"] [m1*m2]
因此,zip
函数从两个列表中创建元组列表,然后使用head
函数将第一个元素提取为元组,而fst
函数则从(字符串,())对。