开发者

Define constructor for newtype

开发者 https://www.devze.com 2023-04-01 22:13 出处:网络
I have a type class IntegerAsType a where value :: a -> Integer data T5 instance IntegerAsType T5 where value _ = 5

I have a type

class IntegerAsType a where
  value :: a -> Integer

data T5
instance IntegerAsType T5 where value _ = 5

newtype (Num a, IntegerAsType n) => PolyRing a n = PolyRing [a]

I've looked around for a way to specify the constructor for the newtype. I realize there can only be one, but I don't see why I can specify what it is.

For example, I might want to only take the first three elements of the argument to the PolyRing value constructor.

I tried adding using a where开发者_C百科 clause at the end of the newtype declaration, but that didn't compile.

I also tried:

(PolyRing xs) = PolyRing [2, 3, 5, 7]

as a toy example. What I think this should do is ignore the argument to the value constructor and always have the value [2,3,5,7]. The code compiles, but my "custom" constructor has no effect.

Is it possible to specify the constructor for a newtype?


I think what you're looking for is a Smart constructor.

PolyRing's basic capitalized constructor cannot be overloaded. But what you can do is this:

polyRing :: (Num a, IntegerAsType n) => [a] -> PolyRing a n
polyRing = PolyRing . take 3

Or, even better:

polyRing :: (Num a, IntegerAsType n) => [a] -> Maybe (PolyRing a n)
polyRing (a:b:c:_) = Just $ PolyRing [a, b, c]
polyRing _         = Nothing

To prevent someone from using the PolyRing constructor directly, your module export declaration at the top of the file could look like this:

module PolyRing (
 PolyRing (), -- Export the PolyRing type but not constructor
 polyRing     -- Your smart constructor
) where

In OO, the unit of encapsulation is the class, but in Haskell, it's the module.

0

精彩评论

暂无评论...
验证码 换一张
取 消