我们自己的数据类型的最大值

sam*_*ena 1 haskell

假设我在 haskell 中创建了自己的数据类型:

data List a = ListNode a (List a) | ListEnd
Run Code Online (Sandbox Code Playgroud)

我如何实现一个自定义的最大值函数来查找列表的最大值,例如:

 mymaximum (ListNode 10 ListEnd)
Run Code Online (Sandbox Code Playgroud)

应该返回 10

mymaximum (ListNode 20 (ListNode 10 ListEnd)) 
Run Code Online (Sandbox Code Playgroud)

将返回 20

ove*_*raw 12

可以定义一个递归函数:

myMaximum :: Ord a => List a -> a
myMaximum (ListNode a ListEnd) = a
myMaximum (ListNode a b) = max a (myMaximum b)
Run Code Online (Sandbox Code Playgroud)

但是,更简洁的解决方案将重用 Haskell 的现有maximum函数,而不是定义您自己的函数

maximum :: forall a . (Foldable t, Ord a) => t a -> a

为此,您需要为 定义(或者,正如其他评论者所指出的,派生)一个Foldable实例List,例如:

instance Foldable List where
  foldMap f ListEnd              = undefined
  foldMap f (ListNode x ListEnd) = undefined
  foldMap f (ListNode x r      ) = undefined
Run Code Online (Sandbox Code Playgroud)

......这,一旦完成,将允许您拨打maximumListS:

?> maximum (ListNode 20 (ListNode 10 ListEnd))
20
Run Code Online (Sandbox Code Playgroud)

  • 您甚至不需要编写 `Foldable` 实例,只需使用 `-XDeriveFoldable` 即可。 (9认同)
  • 或者,“最大值[x,y]”可以写成“max xy”或“x ‘max’ y”。 (2认同)

Sim*_*ine 7

为了扩展 bereal 的评论,sprach 的回答和 leftaroundabout 给出的评论:

{-# LANGUAGE DeriveFoldable #-}

data List a = ListNode a (List a) | ListEnd
  deriving Foldable
Run Code Online (Sandbox Code Playgroud)

然后,类似地,

?> maximum $ ListNode 5 (ListNode 20 (ListNode 10 ListEnd))
20
Run Code Online (Sandbox Code Playgroud)