Haskell 类型构造函数或类错误

Haskell 类型构造函数或类错误,haskell,Haskell,这是我的程序,它给出的错误不在范围内:类型构造函数或类'maxzyklange'如何修复它?类型名称中有一个输入错误: 在maxZyklus的类型签名中,您写的是Maxzyklange小写字母l,但在类型定义中,您写的是Mayzyklange大写字母l。Haskell区分大小写 在maxZyklus的类型签名中: 但你有: ... ,MaxZyklaenge) -- # ^ 它的定义是maxzyklange注意L,而你写的类型是maxzyklange。Haskell是区分大小写

这是我的程序,它给出的错误不在范围内:类型构造函数或类'maxzyklange'如何修复它?

类型名称中有一个输入错误:

在maxZyklus的类型签名中,您写的是Maxzyklange小写字母l,但在类型定义中,您写的是Mayzyklange大写字母l。

Haskell区分大小写

在maxZyklus的类型签名中:

但你有:

 ... ,MaxZyklaenge)
-- #        ^

它的定义是maxzyklange注意L,而你写的类型是maxzyklange。Haskell是区分大小写的。

即使你修正了输入错误,你仍然会得到一个错误,因为length返回一个整数,而你需要一个整数。以下是解决此问题的一种方法,我还重写了您的代码以使用guards:

 type MaxZykLaenge = Integer
-- #        ^
也可以使用fromIntegral。长度,如果你不想额外的导入,但我个人认为genericLength更清晰一些

另外,如果您感兴趣,这里有一种可以说是编写第一个函数的更好方法:

import Data.List (genericLength)

dreiNplusEins :: Integer -> [Integer]
dreiNplusEins 1 = [1]
dreiNplusEins n
  | n `mod` 2 == 0 = n : dreiNplusEins (n `div` 2)
  | otherwise      = n : dreiNplusEins (n * 3 + 1)

maxZyklus :: UntereGrenze -> ObereGrenze -> (UntereGrenze, ObereGrenze, MaxZyklaenge)
maxZyklus m n
 | m == n    = (m, n, genericLength $ dreiNplusEins m)
 | otherwise = (m, n, 0)

type UntereGrenze = Integer
type ObereGrenze  = Integer
type MaxZyklaenge = Integer
dreiNplusEins :: Integer -> [Integer]
dreiNplusEins = (++[1]) . takeWhile (/=1) . iterate f
  where
    f n | even n    = n `div` 2
        | otherwise = n * 3 + 1
这只是说迭代地应用f直到你达到1,然后在末端钉上1

要查找给定范围内产生最长链的数字,可以使用以下函数:

import Data.List (genericLength)

dreiNplusEins :: Integer -> [Integer]
dreiNplusEins 1 = [1]
dreiNplusEins n
  | n `mod` 2 == 0 = n : dreiNplusEins (n `div` 2)
  | otherwise      = n : dreiNplusEins (n * 3 + 1)

maxZyklus :: UntereGrenze -> ObereGrenze -> (UntereGrenze, ObereGrenze, MaxZyklaenge)
maxZyklus m n
 | m == n    = (m, n, genericLength $ dreiNplusEins m)
 | otherwise = (m, n, 0)

type UntereGrenze = Integer
type ObereGrenze  = Integer
type MaxZyklaenge = Integer
dreiNplusEins :: Integer -> [Integer]
dreiNplusEins = (++[1]) . takeWhile (/=1) . iterate f
  where
    f n | even n    = n `div` 2
        | otherwise = n * 3 + 1
第一个参数是创建列表的函数,第二个参数是范围。返回值是一个元组,包含范围内所需的数字及其列表的长度。请注意,我们需要这些额外的导入:

longestBetween :: (Enum a, Integral b) => (a -> [b]) -> (a, a) -> (a, b)
longestBetween f (m, n)
  = maximumBy (comparing snd)
  . zip [m..n] $ map (genericLength . f) [m..n]
我们可以进行如下测试:

import Data.List (genericLength, maximumBy)
import Data.Ord (comparing)
实现您在注释中指定的maxZyklus函数在这一点上只需要做几个小的更改:

*Main> longestBetween dreiNplusEins (100, 1000) 
(871,179)

maxZyklus 11 22给出了所需的11、22、21。

我建议您使用if/then/else,而不是if/then/else。这使函数定义更易于阅读。。。。你是说你有打字错误吗@肯尼特:呵呵,我打字打错了-您知道如何让程序搜索给定间隔m到n之间的Derinplusins的最大长度吗?例如,这里的maxZyklus 11 22程序必须计算每个值11,12,13,14,…22的Dreinplusins的最大长度,并返回最大长度。@marco:类似maximumBy比较snd$zip[m..n]$map length。dreiNplusEins[m..n]其中maximumBy来自数据。列表和比较来自数据。Ord应该能做到这一点。我对这种语言非常陌生。这个程序使用命令maxZyklus 11 22调用并给出11,22,11..22之间的最长列表,当您的程序longest bestween给出整数最长列表长度时,它是真的,例如*Main>lengthDreinplusins 11 15*Main>lengthDreinplusins 12 10*Main>lengthDreinplusins 13 10*Main>lengthDreinplusins 14 18*Main>lengthDreinplusins15 18*Main>LengthDreinplusins 16 5*Main>LengthDreinplusins 17 13*Main>LengthDreinplusins 18 21*Main>LengthDreinplusins 19 21*Main>LengthDreinplusins 20 8*Main>LengthDreinplusins 21*Main>LengthDreinplusins 22 16我们必须将结果长度保存在一个列表中并取最大值这就是我要寻找的