Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
340 views
in Technique[技术] by (71.8m points)

Haskell, find tupel that has minimum 2nd element ,if there are tupels with two same value of 2nd element, then sort with 1st element

example: mymin1 [(3,7),(7,6),(6,6),(5,6)] should returns (5,6)

this is my code:

mymin1 [(x,y)]=(x,y)
mymin1 ((x,y):(x1,y1):xs)
  |y>y1 = mymin1 ((x1,y1):xs)
  |y<=y1 =mymin1 ((x,y):xs)
  |y==y1 = if x>x1 then mymin1((x1,y1):xs) else mymin1((x,y):xs)

which returns (7,6)

any help is appreciated.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Haskell already has an Ord instance for pairs of elements that each have Ord instances, but the instance for pairs compares the first elements before the second. One solution that was already posted is to use minimumBy and supply your own comparing function, but another is to use swap liberally:

import Data.Tuple (swap)

myMin :: (Ord a, Ord b) => [(a, b)] -> (a, b)
myMin = swap . minimum . fmap swap

If you're super concerned about performance, you might be worried that we're traversing the list twice. One way to address this is to use coerce to do a type-safe coercion rather than fmaping swap, but that means we need a data type that is coercible to (a,b). If you're doing a lot of these comparisons, you could consider creating:

newtype Swap a b = Swap { getSwap :: (a,b) }
  deriving(Eq)

instance (Ord a, Ord b) => Ord (Swap a b) where
  compare (Swap (a, b)) (Swap (c, d)) = compare (b,a) (d,c)

With this, you can then write myMin as:

{-# LANGUAGE TypeApplications #-}
import Data.Coerce (coerce)

myMin :: (Ord a, Ord b) => [(a, b)] -> (a, b)
myMin = getSwap . minimum @[] . coerce

(Note that because minimum is polymorphic over the container type and we're using coerce, we need to tell GHC which type of container we're using. Thus, we use the type application @[] after minimum.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
...