Haskell使用保护方程创建类型

Haskell使用保护方程创建类型,haskell,functional-programming,Haskell,Functional Programming,我想创建一个名为two-valued的类型,它包含两个值:a和b,我想确保a这里需要一个ADT(抽象数据类型),因此,首先,正确创建数据类型: data TwoValued a = ValuePair a a deriving Show 然后生成构造函数 makePair :: Ord a => a -> a -> TwoValued a a makePair x y = if x < y then (ValuePair x y) else (ValuePair y x

我想创建一个名为
two-valued
的类型,它包含两个值:
a
b
,我想确保
a这里需要一个ADT(抽象数据类型),因此,首先,正确创建数据类型:

data TwoValued a = ValuePair a a deriving Show
然后生成构造函数

makePair :: Ord a => a -> a -> TwoValued a a
makePair x y = if x < y then (ValuePair x y) else (ValuePair y x)
makePair::Ord a=>a->a->二值a
makePair x y=如果x

最后,用用户需要看到的函数导出模块(在本例中为makePair)

据我所知,您不能在构造函数中定义逻辑。粗体地说,构造函数用于区分值和保存参数

但是,您可以隐藏构造函数,并定义函数来执行构造。例如:

module Foo(TwoValued(), twoValued, firstValue, secondValue)

data TwoValued a = ValuePair { firstValue :: a, secondValue :: a}

twoValued :: Ord a => a -> a -> TwoValued a
twoValued a b | a <= b = ValuePair a b
              | otherwise = ValuePair b a
模块Foo(TwoValue(),TwoValue,firstValue,secondValue) 数据二值a=ValuePair{firstValue::a,secondValue::a} 二值::词a=>a->a->二值a
二值a b | a a
secondValue::二值a->a
,以便其他模块可以获得参数。

智能构造函数是惯用的方法,正如其他模块已经评论过的那样

作为替代方案,我们还可以使用“智能模式构造函数”,它允许超出常规逻辑的逻辑

{-# LANGUAGE PatternSynonyms #-}

module SmartCons(OrdPair(OrdPair)) where

data OrdPair = OP Int Int

pattern OrdPair :: Int -> Int -> OrdPair
pattern OrdPair x y <- OP x y where
   OrdPair x y = if x <= y then OP x y else OP y x
请注意,
OP
哑构造函数只能在模块内访问。从外部来看,我们只能使用智能的


不过,这是个好主意还是个坏主意仍有争议。我想我们还不习惯于期望构造函数包含一些逻辑。将昂贵的计算隐藏在构造后面很容易让用户感到惊讶。

将数据类型声明为正常类型,然后生成一个满足您需要的函数,并将其导出,而不是导出数据构造函数-查看如何实现两种不同类型之间的有序比较…?导出
双值
也是安全的,只是不是
ValuePair
。小尼特:如果使用了智能构造函数,我会省略
Ord a=>
声明中的
data
部分。AFAIRC,这种语法除了限制
two-valued
事物的构造之外,没有别的作用。这在各地都有先例,例如。甚至还有
empty::Map(Int->Int)
虽然
Int->Int
没有
Ord
实例。@SebastianGraf谢谢!我可以把它从答案上抹掉
{-# LANGUAGE PatternSynonyms #-}

module SmartCons(OrdPair(OrdPair)) where

data OrdPair = OP Int Int

pattern OrdPair :: Int -> Int -> OrdPair
pattern OrdPair x y <- OP x y where
   OrdPair x y = if x <= y then OP x y else OP y x
> import SmartCons
> case OrdPair 3 2 of OrdPair x _ -> x
2