简体   繁体   English

Haskell:查找自定义数据类型中的最小值

[英]Haskell: Find the minimum in custom data type

So I have a custom data type, let's call it Struct , defined like this: 因此,我有一个自定义数据类型,我们将其称为Struct ,定义如下:

data Struct = Struct  [SubStruct] deriving (Read, Show)
data SubStruct = SubStruct (Int, Int) deriving (Read, Show)

What I need to do is to go through all the elements in Struct and find the minimum based on fst and then based on the snd . 我需要做的是遍历Struct所有元素,然后根据fst然后根据snd找到最小值。 How do I do that? 我怎么做? More specifically, I want to get another SubStruct such as: 更具体地说,我想获得另一个SubStruct例如:

SubStruct (-2,-5) , based on the example in the code. SubStruct (-2,-5) ,基于代码中的示例。

Currently, i started by doing this: 目前,我首先这样做:

import Data.List
import Data.Function (on)
import Data.List (sortBy)

data Struct = Struct  [SubStruct] deriving (Read, Show)
data SubStruct = SubStruct (Int, Int) deriving (Read, Show  )

struct s sx = Struct(s:sx)

subStruct :: (Int, Int) -> SubStruct
subStruct (x, y) = SubStruct (x, y)

substructs = Struct $ [subStruct (0,1), subStruct (-2, 3), subStruct (4,-5)]

results xs = sortBy (compare `on` fst) (substructs xs)

But I get this error: 但是我得到这个错误:

Couldn't match expected type `t -> [(a, b)]'
            with actual type `Struct'
Relevant bindings include
  xs :: t (bound at bbox.hs:15:9)
  results :: t -> [(a, b)] (bound at file.hs:15:1)
The function `substructs' is applied to one argument,
but its type `Struct' has none
In the second argument of `sortBy', namely `(substructs xs)'
In the expression: sortBy (compare `on` fst) (substructs xs)

Why not use the unzip function. 为什么不使用unzip功能。 If we define an auxiliary function: 如果我们定义一个辅助功能:

unSubStruct :: SubStruct -> (Int, Int)
unSubStruct (SubStruct p) = p

Then the function that returns the element that you want can be written as: 然后,可以将返回所需元素的函数编写为:

getMin :: Struct -> SubStruct
getMin (Struct l) = SubStruct (minimum xs, minimum ys)
  where
    (xs, ys) = unzip $ map unSubStruct l

Note that this will traverse the list twice. 请注意,这将遍历列表两次。 You can avoid that if you define your own version minimum that works on pairs: 如果您定义自己的minimum版本对可以工作,则可以避免这种情况:

getMin :: Struct -> SubStruct
getMin (Struct l) =
    SubStruct $ foldr1 minPair $ map unSubStruct l
  where
    minPair (x0, y0) (x, y) = (min x0 x, min y0 y)

You have a list of SubStruct , which is basically the same as a list of tuples. 您有一个SubStruct列表,该列表与元组列表基本相同。

So, one solution using only common functions would be: 因此,仅使用通用功能的一种解决方案是:

result = SubStruct (min1, min2) where
    min1 = minimum (map fst . list)
    min2 = minimum (map snd . list)
    list = case substructs of
         Struct this -> map (\(SubStruct t) -> t) this

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM