Haskell列表如何输出一个整数的结果?

Haskell列表如何输出一个整数的结果?,haskell,casting,list-comprehension,Haskell,Casting,List Comprehension,我试图使用列表理解来找到一个列表的中位数,该列表始终包含三个整数,函数如下: midNum set = [x | x <- set, x /= maximum set, x /= minimum set]!!0 但是,当我尝试将其与其他函数结合使用时,它会崩溃,导致以下错误: *** Exception: Prelude.!!: index too large 当我移除“!!”!!0',编译器会给我以下消息: Triangle.hs:4:79: error: * Occurs chec

我试图使用列表理解来找到一个列表的中位数,该列表始终包含三个整数,函数如下:

midNum set = [x | x <- set, x /= maximum set, x /= minimum set]!!0
但是,当我尝试将其与其他函数结合使用时,它会崩溃,导致以下错误:

*** Exception: Prelude.!!: index too large
当我移除“!!”!!0',编译器会给我以下消息:

Triangle.hs:4:79: error:
* Occurs check: cannot construct the infinite type: t ~ [t]
* In the second argument of `(+)', namely
    `squareOf (midNum triangle)'
  In the second argument of `(==)', namely
    `squareOf (minimum triangle) + squareOf (midNum triangle)'
  In the expression:
    squareOf (maximum triangle)
    == squareOf (minimum triangle) + squareOf (midNum triangle)
* Relevant bindings include
    triangle :: [t] (bound at Triangle.hs:4:9)
    isRight :: [t] -> Bool (bound at Triangle.hs:4:1)
Failed, modules loaded: none.
因此,函数似乎给了我一个整数,但编译器需要一个列表。在另一种语言中,我会打字来解决这个问题,但我不确定在Haskell中该怎么做


这基本上也是我第一次接触Haskell,所以请原谅我的回答过于明显。

首先,我认为这不起作用,因为为了计算列表的最小值和最大值,需要使用
最小值和
最大值;不是
min
max
。因此,快速解决方法是:

medVal list = [out | out <- list, out /= minimum list, out /= maximum list]

medVal list=[out | out更基本的解决方案

> let midVal x y z | (z>=x)==(x>=y) = x
                   | (x>=y)==(y>=z) = y
                   | otherwise      = z
注:已修复打字错误


它是从真值表中推导出来的,但很容易读取行,例如,如果x小于z且大于y,或者x大于z且y大于x(因此x位于中间)等等。

您可以添加导致错误的代码吗?您的示例应该计算为包含一个元素的列表。您的示例不会进行类型检查,除非您使用
最小值
最大值
,而不是
最小值
最大值
,如果您知道列表总是有3个元素,并且只需要中间值,为什么不使用
e> 排序列表!!1
?我远离我的主计算机atm,因此无法上传错误。此外,我不知道排序功能。但是,类型的这个问题似乎会再次出现,所以我想弄清它的底细。您使用的是哪个
min
min::Ord a=>a->a->a
,因此将其传递给列表不应该进行类型检查。谢谢!我是从内存中写的,所以不是所有的内容都被保留下来。我确实使用了最小值和最大值函数。我回来后会尝试这个修复方法。@MasterArcanist:请注意——正如上一段中所指定的那样——您的函数在语义上仍然不正确。我在编辑之前回复了您的帖子。我对此不满意带有双冒号、Ord a、=>等的iar。当试图解决“学习Haskell非常好”第21页中有关直角三角形的问题时,出现了这个问题,仅使用到目前为止我所学的内容。@MasterArcanist:双冒号用于指定类型签名。您不必指定它,但知道函数操作数的类型和结果的类型是很好的。@MasterArcanist不从内存中发布;请等到您在计算机上确认osted代码实际上按照您所说的方式运行。
midVal 2 5 4
返回
2
?无论如何,上面的逻辑是非常重要的——一些解释会有所帮助。出于某种原因,在解释时可以工作,但在我通过编译器运行时不能。知道为什么吗?在这两种情况下,文本都是复制/粘贴的,只更改了换行/间距在ghci环境中,
let
是必需的,在编译的代码中应该删除它。我确实删除了let。
medVal :: Ord a => [a] -> a
medVal list = [out | out <- list, out /= minimum list, out /= maximum list]!!0
medVal :: Ord a => [a] -> a
medVal list = head [out | out <- list, out /= minimum list, out /= maximum list]
> let midVal x y z | (z>=x)==(x>=y) = x
                   | (x>=y)==(y>=z) = y
                   | otherwise      = z