自定义数据类型过滤器 - 任何数字类型

时间:2018-03-25 07:39:22

标签: haskell filter custom-data-type

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  
    
  6. 您收到以下错误:

    * 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)
    

1 个答案:

答案 0 :(得分:-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程序员,但是这个可行。