是否可以让类型预成型函数成为其值之一,以生成另一个值?例如:
data Foo=Foo {valueOne::Int, valueTwo=valueOne*2} deriving (Bar)
或者我是以错误的方式思考这个问题?任何帮助表示赞赏!
答案 0 :(得分:9)
如果总是希望第二个字段依赖于第一个字段,那么只需编写一个普通函数:
data Foo = Foo { valueOne :: Int } deriving (Bar)
valueTwo :: Foo -> Int
valueTwo x = valueOne x * 2
唯一的区别是自动生成的Bar
实例不会注意到第二个字段。
相反,如果您希望生成具有此类约束的值,但仍有时可以忽略它,请使用智能构造函数:
data Foo = Foo { valueOne :: Int, valueTwo :: Int } deriving (Bar)
foo :: Int -> Foo
foo x = Foo x (2 * x)
如果使用foo
而不是Foo
来构造新值,则不需要传递第二个参数,该参数将从第一个参数派生。
通常这在module
中使用,它不导出构造函数Foo
,但导出智能构造函数foo
。通过这种方式,模块的用户被约束为构建满足不变量的值,而模块中的函数可以在需要时忽略它。