-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Promoting Enum instance #136
Comments
@vagarenko, those functions are only for derivable instances. But, @vladfi1, if you just wrap your instance definition in |
If this doesn't work, please reopen. Thanks! |
Here's what I have: {-# LANGUAGE DataKinds,
PolyKinds,
TypeOperators,
TypeFamilies,
GADTs,
UndecidableInstances,
KindSignatures,
InstanceSigs,
ScopedTypeVariables,
TemplateHaskell
#-}
module SingletonsTH where
import Data.Singletons.Prelude
import Data.Singletons.TH
$(singletons [d|
data Nat = Z | S Nat
deriving (Eq, Ord, Show)
instance Enum Nat where
succ = S
pred Z = error "pred Z"
pred (S n) = n
toEnum 0 = Z
toEnum n = S $ toEnum (n-1)
fromEnum Z = 0
fromEnum (S n) = 1 + (fromEnum n)
|]) This fails with
Now that I've manually implemented PEnum, SEnum, PNat, and SNat for this type I'm not sure if I should expect singletons to be able to do it. In particular, sToEnum/sFromInteger required some unsafeCoerce business, and I wasn't even able to write sFromEnum. At least Apply just works! |
This worked for me:
I identify three problems here:
(1) and (3) are proper bugs. (2) is essentially a feature request. But, if I recall, (2) is trickier than you would think. (1) and (3) should be possible though. In the meantime, (1) and (3) are very easy to work around. |
Cool, that works. I can now promote both Enum and Num instances! I'm curious how singletons is able to promote toEnum and fromEnum though (as I said, I had difficulty doing it manually). |
You can always take a look at |
I've run into more trouble, again with promoting Enum instances. {-# LANGUAGE GADTs, DataKinds, PolyKinds, TypeFamilies, KindSignatures #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
{-# LANGUAGE InstanceSigs, DefaultSignatures #-}
module Binary where
import Data.Singletons.TH
import Data.Singletons.Prelude
import Data.Singletons.Prelude.Enum
import Data.Singletons.Prelude.Num
type Bit = Bool
type BiNat = [Bit]
$(singletons [d|
instance Enum BiNat where
succ [] = [True]
succ (False:as) = True : as
succ (True:as) = False : succ as
pred [] = error "pred 0"
pred (False:as) = True : pred as
pred (True:as) = False : as
toEnum i | i < 0 = error "negative toEnum"
| i == 0 = []
| otherwise = succ (toEnum (pred i))
fromEnum [] = 0
fromEnum (False:as) = 2 * fromEnum as
fromEnum (True:as) = 1 + 2 * fromEnum as
|]) The toEnum definition causes problems such as
The fromEnum [] case also causes an error:
|
This commit is a definite improvement w.r.t. #136, but it doesn't fully fix it. Still outstanding is the fact that the expression `... | otherwise = succ (toEnum (pred i))` is just too involved for singletons to figure out how to specialize succ. Wait. Never mind. I've figured out how to do it.
This fixes the example program by propagating type information down through `case`. But there's still the eta-expansion of methods mentioned in the ticket.
I have a type for which Enum is not derivable, but I have instead written my own Enum instance. Is there a way to get singletons to promote this instance, giving me the PEnum, SEnum, and Apply instances I want?
The text was updated successfully, but these errors were encountered: