首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >正确使用

正确使用
EN

Stack Overflow用户
提问于 2011-01-23 00:37:12
回答 2查看 1.1K关注 0票数 0

因此,我有以下功能:

代码语言:javascript
复制
chk2 :: [(Integer,Integer)] -> Either [(Integer,Integer)] (Integer,Integer)
chk2 i@((n,_):_)
  | chkp (prod $ lgst i)==True = Right $ lgst i
  | lgst i==i!!0 = Left $ chk2 $ (4-2,4-2):next i                                           
  | otherwise = Left $ chk2 $ next i
  where prod (a,b) = a*b
        lgst = foldl1 (\(a,b) (c,d) -> if prod (a,b) > prod (c,d) then (a,b) else (c,d))
        next t = map (\(a,b) -> if (a,b)==lgst t then (a-1,b+1) else (a,b)) t

连同这个错误:

代码语言:javascript
复制
runhugs: Error occurred
ERROR "4/4.hs":14 - Type error in explicitly typed binding
*** Term           : chk2
*** Type           : [(Integer,Integer)] -> Either (Either [(Integer,Integer (Integer,Integer)) (Integer,Integer)
*** Does not match : [(Integer,Integer)] -> Either [(Integer,Integer)] (Integer,Integer)

我试图让这个函数得到一个(a,b),即第一个守卫,或者(a,b),即后两个守卫。最基本的问题是后两名警卫。如果去掉递归,一切都会正常工作,但我不知道如何在返回函数本身时定义类型签名。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-01-23 00:51:45

问题是你怎么恢复。

根据chk2的类型,chk2 $ next i属于Either [(Integer,Integer)] (Integer,Integer)型。Leftb -> Either b a类型,因此对于某些未指定类型的aLeft $ chk2 $ next iEither (Either [(Integer,Integer)] (Integer,Integer)) a类型。

Left $ chk2 $ (4-2,4-2):next i也有类似的问题。

要修复,您需要决定如何处理递归值。

容易修复:

代码语言:javascript
复制
  | lgst i==i!!0 = chk2 $ (4-2,4-2):next i                                           
  | otherwise = chk2 $ next i

然而,我怀疑这是您想要的,因为这意味着您的所有结果将是Right。我不知道怎么做你想做的,因为我不知道你想要什么。

列表结果意味着什么?无名单的结果意味着什么?

您可能要做的是,模式匹配递归的结果,转换Right pair -> Left [pair],或者将其他一些结果附加到前面。

例如,我将构造一个具有类似类型签名的递归函数。设foo是一个接受整数列表的函数,并且:

  • 如果列表的第一个元素是整个列表的最大值,则返回该元素。
  • 否则,返回列表的子序列,其中每个元素是它与子序列(或结尾)中的下一个元素之间所有元素的最大值。

为此,请执行以下操作:

代码语言:javascript
复制
foo :: [Integer] -> Either [Integer] Integer
foo [] = Left []
foo (x:xs) = case foo xs of
  Left ys -> if all (<=x) ys
              then Right x
              else let (_,ys') = break (>x) ys in Left (x:ys')
  Right y -> if x >= y
              then Right x
              else Left [x,y]

注意如何使用casefoo的递归调用结果进行模式匹配。

票数 3
EN

Stack Overflow用户

发布于 2011-01-24 00:58:24

要解决欧拉#4,你的似乎是一个非常尴尬的风格Haskell。尝试将其他语言的“端口”代码移植到Haskell通常是个坏主意,因为Haskell的范例非常不同。

您将找到一个非常干净、合理的Euler #4解决方案,它使用列表理解在Haskell Wiki。当然不是唯一的解决方案,但它至少与当前代码一样可读性为20倍。无意冒犯。

我(和许多其他Haskeller)强烈推荐给你一个哈斯克尔真实世界Haskell来学习如何以Haskell的方式处理问题,在我的经验中,通常是创建小型的简单助手方法并将它们组合成一个解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4771584

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档