[英]Haskell return single tuple after recursion
我在玩.bmp图像和ascii艺术,遇到了一个有关模式匹配和元组递归的问题。
该函数只需要简单地将单词列表转换为整数即可。在不改变高度和宽度的情况下。 我的尝试:
convertToIntegers :: ([GHC.Word.Word8], Integer, Integer) -> ([Integer], Integer, Integer)
convertToIntegers ([], x, y) = ([], x, y)
convertToIntegers ((a:as), x, y) = ( toInteger a : convertToIntegers (as, x, y), x, y)
显然,这不起作用并返回类型错误:
Couldn't match expected type `[Integer]' with actual type `([Integer], Integer, Integer)'
In the return type of a call of `convertToIntegers'
In the second argument of `(:)', namely `convertToIntegers (as, x, y)'
In the expression: toInteger a : convertToIntegers (as, x, y)
看起来应该很简单,我可以通过拆分并使用辅助函数来完成它。 为了弄清楚这一点,我尝试了以下方法:
convertToIntegers :: ([GHC.Word.Word8], Int, Int) -> [Integer]
convertToIntegers ([], x, y) = []
convertToIntegers ((a:as), x, y) = toInteger a : convertToIntegers (as, x, y)
这很好。 因此,问题在于,我根本不知道在操作其中的列表时如何返回单个元组。 真是烦我,有人可以帮忙吗?
为什么不只是使用地图?
convertToIntegers :: ([GHC.Word.Word8], Integer, Integer) -> ([Integer], Integer, Integer)
convertToIntegers (as, x, y) = (map toInteger as, x, y)
编辑:
您的主要问题是这里有一个实际的错误:
( toInteger a : convertToIntegers (as, x, y), x, y)
^ ^ ^
您正在返回一个元组作为另一个元组的第一个参数,在类型签名中您声称要返回一个整数列表。 如果您不想使用地图,则可以这样编写:
convertToIntegers :: ([GHC.Word.Word8], Integer, Integer) -> ([Integer], Integer, Integer)
convertToIntegers (as, x, y) = (convertWords as, x, y)
where
convertWords [] = []
convertWords (z:zs) = toInteger z : convertWords zs
编写此使用模式的标准方法是let
:
convertToIntegers :: ([GHC.Word.Word8], Integer, Integer) -> ([Integer], Integer, Integer)
convertToIntegers ([], x, y) = ([], x, y)
convertToIntegers ((a:as), x, y) = let (rs, x2, y2) = convertToIntegers (as, x, y)
in (toInteger a : rs, x2, y2)
Haskell的let
是递归的; 如果要在let
的定义的两侧使用x,y
,则将阴影外部名称x,y
(阻止对它们的访问)。 这样x,y
方程式RHS上的x,y
引用了LHS上的外部参数x,y
,而LHS上的x2,y2
用于传递从内部函数调用返回的值。
这并不意味着将在返回值之前进行此调用。 恰恰相反,由于Haskell的懒惰,首先构造带有孔(_1, _2, _3)
的返回值(三元组(_1, _2, _3)
,只有在访问这些孔时,才根据定义触发进一步的评估,其中_1 = toInteger a : rs
, _2 = x2
, _3 = y2
。 因此,如果该访问为head _1
,则不会触发任何函数调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.