【问题标题】:Custom Data Type Filter - Any Numerical Type自定义数据类型过滤器 - 任何数字类型
【发布时间】:2018-03-26 23:06:23
【问题描述】:
import System.IO()

data Point = Point
    { pointX :: {-# UNPACK #-} !Double  -- ^ X coordinate
    , pointY :: {-# UNPACK #-} !Double  -- ^ Y coordinate
    } deriving (Show, Eq)

data Polygon = Polygon
    { points :: [Point]
    , yvalue :: Int
    } deriving (Show)
  1. 创建文件test.hs
  2. 将上面的两个自定义数据类型定义复制进去
  3. 打开ghci并输入:l test.hs
  4. 输入这个测试用例:

    *test> let a = Polygon {points = [Point {pointX = 0.0, pointY = 0.0},Point {pointX = 4.0, pointY = 0.0},Point {pointX = 4.0, pointY = 2.0},Point {pointX = 4.0, pointY = 4.0},Point {pointX = 0.0, pointY = 4.0},Point {pointX = 0.0, pointY = 2.0},Point {pointX = 0.0, pointY = 0.0}], yvalue = 2}
    
  5. 然后:

    *test> let x = filter (<=(fromIntegral (yvalue a)).pointY) $ points a  
    

您收到以下错误:

* couldn't match type `Point` with `Point -> c'
  Expected type: [Point -> c]
    Actual type: [Point]
* In the second argument of `($)', namely `points a'
  In the expression:
    filter (<=(fromIntegral (yvalue a)) . pointY) $ points a
  In an equation for `x':
    x = filter (<=(fromIntegral (yvalue a)).pointY) $ points a  
* Relevant bindings include
    x :: [Point -> c] (bound at <interactive>:92:5)

【问题讨论】:

  • 你的意思是像filter ((&gt;= someThreshold) . pointY)
  • 这让我更接近了。我添加了多边形结构。这将错误更改为:无法匹配类型Point -&gt; c0' with Point' 预期类型:[Point] 实际类型:[Point -> c0]
  • 您可以将当前代码与您用于上下文的已知类型的标识符一起粘贴吗?
  • 我认为编辑应该包括唯一缺少的东西。有一条不同的线返回周长。
  • 这可能是一个简单的语法问题;没有minimal reproducible example 就很难确认。但你没有按我说的做:let threshold = fromIntegral (yvalue x); ... filter ((&gt;= threshold) . pointY)

标签: haskell filter custom-data-type


【解决方案1】:

解决办法是:

如果您希望按特定的数字数据类型字段进行过滤,那么您只需实现一个比较实例。

就我而言:

instance Ord Point where
    compare x y = compare (pointY x) (pointY y)

这将我希望比较的指定字段设置为 pointY,它已经是 Double 的实例。

然后我可以使用以下过滤器:

filter(\x -> x > Point {pointX = 0.0, pointY = (fromIntegral(yvalue))} $ points a

注意:这个过滤器中的 pointX 是完全不相关的。

可能会出现另一种解决方案,因为这里有一些出色的 Haskell 程序员,但这个可行。

【讨论】:

  • 如果2天内没有添加其他解决方案,我会标记为已回答。
  • Ord 实例非常不正常,尤其是Point 1 0 &lt; Point 0 0Point 1 0 &gt; Point 0 0 都将是False,尽管这两点显然不相等。 2D 点不能形成正确的 Ord 实例。 — 你为什么不用filter ((&lt;fromIntegral yValue) . pointY) $ points a
  • 为什么不简单地 filter (\ p -&gt; pointY p &gt; fromIntegral yvalue) $ points a,没有一次性(和虚假)Ord 实例。
  • leftaroundabout 这听起来就像我开始的,几乎完全一样,它不会将这一点与双倍进行比较。我无法让它工作。
  • 您的解决方案是否会自然而然地发挥作用,而且肯定会更好。我正在做我正在做的事情,因为我已经做haskell大约2周了。因此,如果您将其写下来,我会选择它已回答,尽管您似乎不需要积分。我找不到任何简单说明如何访问数值进行比较的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 2020-04-09
  • 2011-06-17
相关资源
最近更新 更多