Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
haskell中列表的第K个元素_Haskell - Fatal编程技术网

haskell中列表的第K个元素

haskell中列表的第K个元素,haskell,Haskell,我是haskell的初学者,正在尝试实现一个函数,该函数返回列表的第k个元素,而不使用前奏!!内置的 kth_i [] _ _ = -1 kth_i (x:xs) i k = if i == k then x else kth_i xs (i + 1) k kth xs k = kth_i xs 0 k 这段代码可以工作,但太冗长了。我只想使用一个函数 编辑:我最终得到了: let kth (x:xs) k = if k == 0 then x else if k < 0 then er

我是haskell的初学者,正在尝试实现一个函数,该函数返回列表的第k个元素,而不使用前奏!!内置的

kth_i [] _ _ = -1
kth_i (x:xs) i k = if i == k then x else kth_i xs (i + 1) k
kth xs k = kth_i xs 0 k
这段代码可以工作,但太冗长了。我只想使用一个函数

编辑:我最终得到了:

let kth (x:xs) k = if k == 0 then x else if k < 0 then error "out of bounds" else  kth xs (k - 1); kth [] _ = error "out of bounds"

按照@Carsten的建议

所以我想你找到了解决方案,但请允许我为你做得更好一点:

kth :: [a] -> Integer -> a
kth (x:xs) i
   | i < 0  = error "out of bounds"
   | i == 0 = x
   | i > 0  = kth xs (i-1)
kth [] _    = error "empty list"

这使用而不是ifs-因此,如果您之前没有看到这些,您可能应该按照链接阅读wiki

,因此我想您找到了解决方案,但请允许我为您做得更好一些:

kth :: [a] -> Integer -> a
kth (x:xs) i
   | i < 0  = error "out of bounds"
   | i == 0 = x
   | i > 0  = kth xs (i-1)
kth [] _    = error "empty list"
这使用而不是ifs-因此,如果您之前没有看到这些,您可能应该按照链接阅读wiki更新:以下是使用模式匹配的解决方案。您还可以查看Haskell的实现!!与此代码非常相似的函数:

更新:以下是使用模式匹配的解决方案。您还可以查看Haskell的实现!!与此代码非常相似的函数:


一个简单的定义,假设列表至少有k+1项:


一个简单的定义,假设列表至少有k+1项:


由于没有其他人提到这一点,我想我应该这样做:Haskell通常不鼓励使用部分函数——有时会导致错误消息或无限循环的函数。我们倾向于处理全部函数,使用诸如Maybe和other之类的类型表示失败。即使在处理部分函数时,我们也会试图限制难以处理的错误。最极端的版本可能是这样的:

data Kth a = NegativeIndex | ShortList | Kth a

kth :: Integral i => [a] -> i -> Kth a
kth _ k | k < 0 = NegativeIndex
kth [] _ = ShortList
kth (x : _) 0 = Kth x
kth (_ : xs) k = kth xs (k - 1)
kth' xs = foldr go (const Nothing) xs where
  go x _ 0 = Just x
  go _ r i = r (i - 1)
一旦我们走到了这一步,我们可能会有更多的乐趣。helper函数与foldr设计模式匹配,因此我们可以这样编写:

data Kth a = NegativeIndex | ShortList | Kth a

kth :: Integral i => [a] -> i -> Kth a
kth _ k | k < 0 = NegativeIndex
kth [] _ = ShortList
kth (x : _) 0 = Kth x
kth (_ : xs) k = kth xs (k - 1)
kth' xs = foldr go (const Nothing) xs where
  go x _ 0 = Just x
  go _ r i = r (i - 1)
内联这个版本的kth’,我们得到


出于优化目的,最好用'seq'Nothing替换const Nothing,用r$替换ri-1!i-1,但现在详细说明原因可能不是一个好主意

因为没有其他人提到这一点,我想我应该这样做:Haskell通常不鼓励使用有时会导致错误消息或无限循环的部分函数。我们倾向于处理全部函数,使用诸如Maybe和other之类的类型表示失败。即使在处理部分函数时,我们也会试图限制难以处理的错误。最极端的版本可能是这样的:

data Kth a = NegativeIndex | ShortList | Kth a

kth :: Integral i => [a] -> i -> Kth a
kth _ k | k < 0 = NegativeIndex
kth [] _ = ShortList
kth (x : _) 0 = Kth x
kth (_ : xs) k = kth xs (k - 1)
kth' xs = foldr go (const Nothing) xs where
  go x _ 0 = Just x
  go _ r i = r (i - 1)
一旦我们走到了这一步,我们可能会有更多的乐趣。helper函数与foldr设计模式匹配,因此我们可以这样编写:

data Kth a = NegativeIndex | ShortList | Kth a

kth :: Integral i => [a] -> i -> Kth a
kth _ k | k < 0 = NegativeIndex
kth [] _ = ShortList
kth (x : _) 0 = Kth x
kth (_ : xs) k = kth xs (k - 1)
kth' xs = foldr go (const Nothing) xs where
  go x _ 0 = Just x
  go _ r i = r (i - 1)
内联这个版本的kth’,我们得到


出于优化目的,最好用'seq'Nothing替换const Nothing,用r$替换ri-1!i-1,但现在详细说明原因可能不是一个好主意

你从0数到k。。。如果你从k倒数到0呢?也许你可以摆脱i?顺便说一句:第一行将强制你的结果类型进入numa,这是不必要的-!!是部分的,如果列表为空,则会失败-因此,您也可以使用undefined或error empty list,而不是右侧的-1,或者如果愿意,可以完全删除该案例!另外,你应该想想那些可能会向你索要kth xs-1的讨厌的用户——也许这应该是一个错误,而不是一个永远不回的电话?谢谢!设kthx:xsk=如果k==0,则x否则kthxsk-1;kth[].=-1现在我只需要处理错误,我已经让kth x:xs k=如果k==0,那么x else如果k<0,那么错误超出范围,否则kth xs k-1;kth[].=error out-out-bounds,适用于正指数,但kth[0..5]-1返回:约束中的非类型变量参数:Num a->t您必须使用kth[0..5]输入它-1您从0到k计数。。。如果你从k倒数到0呢?也许你可以摆脱i?顺便说一句:第一行将强制你的结果类型进入numa,这是不必要的-!!是部分的,如果列表为空,则会失败-因此,您也可以使用undefined或error empty list,而不是右侧的-1,或者如果愿意,可以完全删除该案例!另外,你应该想想那些可能会向你索要kth xs-1的讨厌的用户——也许这应该是一个错误,而不是一个永远不回的电话?谢谢!设kthx:xsk=如果k==0,则x否则kthxsk-1;kth[].=-1现在我只需要处理错误,我已经让kth x:xs k=如果k==0,那么x else如果k<0,那么错误超出范围,否则kth xs k-1;kth[].=error out-out-bounds,适用于正索引,但kth[0..5]-1返回:约束中的非类型变量参数:Num a->tyu必须使用kth[0..5]输入它,-1为什么类型声明是必需的,不是由编译器推断出来的吗?是的,编译器确实会通过

去掉整数-但最好在顶级定义中添加签名-如果不这样做,编译器甚至会警告你-如果你做错了什么,它会帮助你经常出现类型错误,这是很有价值的文档@dimid,从某种意义上说,推断出的签名过于笼统,它将允许您使用诸如Double和Rational之类的数字类型,这将导致奇怪的行为。最好限制一下。通常,此函数的泛型版本将被赋予签名kth::Integral i=>[a]->i->a。为什么需要类型声明,它不是由编译器推断出来的吗?是的,编译器确实会通过去掉整数使它更加通用-但最好是在顶级定义中添加签名-编译器甚至会警告你如果你没有-如果你做错了什么,它会帮助你经常出现类型错误,这是很有价值的文档@dimid,从某种意义上说,推断出的签名过于笼统,它将允许您使用诸如Double和Rational之类的数字类型,这将导致奇怪的行为。最好限制一下。通常,此函数的通用版本会被赋予签名kth::Integral i=>[a]->i->a。我认为问题是如何去掉第二个函数kth_i,但是的,这当然有效……您不想将自己限制在整数列表中。@Carsten谢谢!我以为OP是说不要使用模式匹配。更新了答案我想问题是如何摆脱kth_i,这是第二个函数,但是的,这当然有效……你不想把自己限制在整数列表中。@Carsten谢谢!我以为OP是说不要使用模式匹配。更新了答案非常感谢您的详细回答!但愿我能投票两次:如果我理解正确,你答案中的所有版本都是部分函数。如果是这样,那么整个函数会是什么样子?还有,为什么第一个版本“难以使用”?@dimid,第一个是total。第二个和第三个可以通过替换错误。。。“没有什么,但没有什么会有两个潜在的含义”。@dimid,可能比那个奇怪的类型有更多的工具。我想,您可以通过声明data BadNth=NegativeIx | TooShort,然后使用任意一个BadNth a来解决这个问题。非常感谢您提供的详细答案!但愿我能投票两次:如果我理解正确,你答案中的所有版本都是部分函数。如果是这样,那么整个函数会是什么样子?还有,为什么第一个版本“难以使用”?@dimid,第一个是total。第二个和第三个可以通过替换错误。。。“没有什么,但没有什么会有两个潜在的含义”。@dimid,可能比那个奇怪的类型有更多的工具。我想,您可以通过声明data BadNth=NegativeIx | TooShort,然后使用任意一个BadNth a来解决这个问题。