简体   繁体   English

Haskell,递归数据和模式匹配

[英]Haskell, recursive data and pattern matching


is the first time that I work with the recursive data . 这是我第一次使用递归data I can not solve this problem: 我无法解决此问题:

data Sseq = S Sseq | E deriving (Show)

testElem = (S, S, E, S)

maxSseq_hlp :: Int -> Int -> [SSeq] -> Int
maxSseq_hlp curmax prevmax [] = max curmax prevmax
maxSseq_hlp curmax prevmax ((S x):xs) = maxSSeq_hlp (curmax+1) prevmax xs
maxSseq_hlp curmax prevmax (E:xs) = maxSSeq_hlp 0 (max curmax prevmax) xs

maxSseq :: [SSeq] -> Int
maxSseq list = maxSseq_hlp 0 0 list

The function maxSseq should return the longest sequence S in a list testElem, using an auxiliary function that remembers the S counted in the previous sequences, but gives me the following error 函数maxSseq应该使用一个辅助函数返回列表testElem中最长的序列S,该函数记住前面序列中计数的S,但给我以下错误

Couldn't match expected type `[Sseq]'
            with actual type `(Sseq -> Sseq,
                               Sseq -> Sseq,
                               Sseq,
                               Sseq -> Sseq)'
In the first argument of `maxSseq', namely `testElem'
In the expression: maxSseq testElem
In an equation for `it': it = maxSseq testElem

I do not understand where is the problem, can you help me please? 我不明白问题出在哪里,请您能帮我吗?

Ok one after the other: 一次又一次地确定:

tuple vs lists 元组与列表

Your testElem is not really a list - it is a tuple - so you have to write [..] instead of (..) 您的testElem实际上不是一个列表-它是一个元组-因此您必须写[..]而不是(..)

constructors 建设者

Your Sseq can either be E or S s where s itself has to be a Sseq again - so your testElem will not work this way (that's why you got the error saying you used functions Sseq -> Sseq (those are the S ) 您的Sseq可以是ES s ,其中s本身必须再次是Sseq因此您的testElem将无法以这种方式工作(这就是为什么您收到错误消息,指出您使用了函数Sseq -> Sseq (这些是S

I would suggest: 我会建议:

testElem :: [Sseq]
testElem = [S E, S (S (S E)), E, S (S E)]

this should evaluate (IMO) to either 3 or S (S (SE)) depending on your desired behavior of maxSseq (see below) 这应该根据您期望的maxSseq行为将(IMO)评估为3S (S (SE)) (请参阅下文)

Use this and try again (I guess this is Homework of some sort) 使用它,然后重试(我想这是某种形式的家庭作业)

PS PS

all the other errors you will see will basically come from misspelling something - mostlikely SSeq VS Sseq ;) 您将看到的所有其他错误基本上都来自拼写错误的内容-最有可能是SSeq VS Sseq ;)

more hints: 更多提示:

  • Your function will not work (you consume max. one of the S while counting) 您的函数将不起作用(计数时最多消耗S之一)
  • You can try to fix this by cleverly reinserting the x from (S x)::xs 您可以尝试通过从(S x)::xs重新插入x来解决此问题
  • But I think what you really want to do is first implement a function len :: Sseq -> Int and then use this cleverly in some way 但是我认为您真正想做的是先实现len :: Sseq -> Int函数,然后以某种方式巧妙地使用它
  • based on your description, what you really want is maxSseq :: [Sseq] -> Sseq - so if you stick with your code you have to remember the max. 根据您的描述,您真正想要的是maxSseq :: [Sseq] -> Sseq因此,如果您坚持使用自己的代码,则必须记住最大值。 seqence not (only) it's length 序列不是(仅)它的长度
  • if you are interested you can use my former hint to solve this easily using comparing and maximumBy 如果你有兴趣,你可以用我的前提示这一点很容易使用,以解决比较maximumBy

I will append my full solution in an hour or so but you should really try it out yourself first. 我会在一个小时左右的时间内附加完整的解决方案,但您应该首先自己尝试一下。

solutions (don't read if you are still trying) 解决方案(如果您仍在尝试,请不要阅读)

ok this is how you can patch your solution: 好的,这是修补解决方案的方法:

maxSseq_hlp :: Int -> Int -> [Sseq] -> Int
maxSseq_hlp curmax prevmax [] = max curmax prevmax
maxSseq_hlp curmax prevmax ((S x):xs) = maxSseq_hlp (curmax+1) prevmax (x:xs)
maxSseq_hlp curmax prevmax (E:xs) = maxSseq_hlp 0 (max curmax prevmax) xs

and this is what I would advise if you need to find the max. 这就是我建议您是否需要找到的最大值。 length element : 长度元素

import Data.List (maximumBy)
import Data.Ord (comparing)

len :: Sseq -> Int
len E = 0
len (S x) = 1 + len x

maxSseq :: [Sseq] -> Sseq
maxSseq = maximumBy (comparing len)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM