Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to push foralls past constructors when sound?

Tags:

haskell

Suppose I have

data Foo p =
    NoFoo
  | YesFoo (forall a. p a)

I can write

fromFoo :: Foo p -> Maybe (p a)
fromFoo NoFoo = Nothing
fromFoo (YesFoo p) = Just p

It's also possible to go the other way:

toFoo :: forall p.
         (forall a. Maybe (p a))
      -> Foo p
toFoo m =
  case m :: Maybe (p ()) of
    Nothing -> NoFoo
    Just _ -> YesFoo (fromJust m)

The fromJust is disgusting! toFoo is actually total, because parametricity ensures that m @a behaves exactly the same as m @(), but this is gross. Is there any cleaner way?

Edit: rampion pointed out that this can be written more concisely, still with fromJust. I just realized it can be done a bit humorously, making fun of the newbies:

toFoo m
  | isNothing m = NoFoo
  | otherwise = YesFoo (fromJust m)

The only way I see to avoid creating a thunk to apply fromJust is by getting super-evil:

toFoo Nothing = NoFoo
toFoo (Just x) = YesFoo (unsafeCoerce# x)
like image 930
dfeuer Avatar asked Jul 07 '17 01:07

dfeuer


People also ask

How do you win the constructors championship?

The Constructors' Championship is won when it is no longer mathematically possible for another constructor to overtake another's points total regardless of the outcome of the remaining races, although it is not officially awarded until the FIA Prize Giving Ceremony held in various cities following the conclusion of the ...

Can Red Bull win Constructors championship 2022?

Red Bull sealed the 2022 Formula 1 constructors' championship as Max Verstappen won the United States Grand Prix in Austin on Sunday. The title, which is paired with Verstappen's second successive triumph in the drivers' championship, is Red Bull's first since 2014, and ends an eight-year streak of Mercedes domination.

Who is the most successful Formula 1 driver?

Lewis Hamilton - 103 wins. In terms of career wins and total career points, Lewis Hamilton is the best Formula 1 driver to have ever graced a circuit.


1 Answers

The best I can come up with so far still uses fromJust, but it's simpler:

toFoo :: forall p.
         (forall a. Maybe (p a))
      -> Foo p
toFoo Nothing = NoFoo
toFoo m = YesFoo $ fromJust m
like image 60
rampion Avatar answered Sep 26 '22 02:09

rampion