I made a TH function earlier this year to produce types for constructors:

data Foo = LeftFoo !Int | RightFoo !Char
    deriving Show

$(constructorType 'LeftFoo)
deriving instance Show LeftFooC

In a repl you can see it generates a type with a single constructor, an introducer, and an eliminator.

*Main> :browse
type Foo :: *
data Foo = LeftFoo !Int | RightFoo !Char
type LeftFooC :: *
data LeftFooC = LeftFooC Int
introLeftFooC :: Foo -> Maybe LeftFooC
elimLeftFooC :: LeftFooC -> Foo

*Main> introLeftFooC (RightFoo 'a')
Nothing

*Main> introLeftFooC (LeftFoo 123)
Just (LeftFooC 123)

*Main> elimLeftFooC $ LeftFooC 456
LeftFoo 456

If you find that useful, I ripped it out of my other repo and pasted it here: https://gist.github.com/plredmond/5fd15fb388647b248de87693542d2adb

On Thu, Sep 1, 2022 at 3:54 PM Ruben Astudillo <ruben.astud@gmail.com> wrote:
On 01-09-22 16:33, Dominik Schrempf wrote:
> Chiming in here, maybe I missed something. Liquid Haskell is great, but in this
> case, in my opinion, easier is better:
>
> newtype LeftFoo = LeftFoo !Int
>
> newtype RightFoo = RightFoo !Char
>
> data Foo = LFoo LeftFoo | RFoo RightFoo – Probably with strictness annotations.
>
> isLeftFoo :: Foo -> Bool
> isLeftFoo (LFoo _) = True
> isLeftFoo _ = False
>
> takesOnlyLeftFoo :: LeftFoo -> Int
> takesOnlyLeftFoo (LeftFoo i) = i
>
> Dominik

Chiming in here too. I do this all the time if the subpart is to be used on
2 or more places. Easiest way to do this without extensions.

--
Rubén. (pgp: 1E88 3AC4 89EB FA22)

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.