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