[Haskell-cafe] Mapping over Type Level Literals
Marcin Mrotek
marcin.jan.mrotek at gmail.com
Wed Sep 17 10:45:22 UTC 2014
Now I see that since you don't have a type list anywhere in the return
type, you might try to use type classes:
(works with GHC context stack set to at least one more than the value of N)
-------
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE PolyKinds #-}
import GHC.TypeLits
import Data.Proxy
import Data.Singletons
data Haar (a :: Nat) (b :: Nat) = Haar { unHaar :: Double -> Double }
haar :: forall n k .
(KnownNat n, KnownNat k, (2 * k - 1 <=? 2^n - 1) ~ 'True) =>
Haar n (2 * k - 1)
haar = Haar g where
g t | (k' - 1) * 2 ** (-n') < t && t <= k' * 2 ** (-n') = 2
** ((n' - 1) / 2)
| k' * 2 ** (-n') < t && t <= (k' + 1) * 2 ** (-n') = -2
** ((n' - 1) / 2)
| otherwise = 0
where
n' = fromIntegral (natVal (Proxy :: Proxy n))
k' = 2 * (fromIntegral (natVal (Proxy :: Proxy k))) - 1
data Natural = Z | S Natural
type family FromNat n where
FromNat Z = 0
FromNat (S n) = 1 + (FromNat n)
type family ToNat i where
ToNat 0 = Z
ToNat n = S (ToNat (n - 1))
class Upto n where
upto :: sing n -> [Integer]
instance Upto Z where
upto _ = []
instance (KnownNat (FromNat n), Upto n) => Upto (S n) where
upto _ = natVal (undefined :: sing (FromNat n)) : upto (undefined :: sing n)
class MapHaar (n :: Nat) (xs :: [(Nat,Nat)]) where
maphaar :: sing1 n -> sing2 xs -> [[(Double, Double)]]
instance MapHaar n '[] where
maphaar _ _ = []
instance (Upto (ToNat n), MapHaar n xs, b ~ (2 * k - 1), b <= 2^a - 1,
KnownNat n, KnownNat k, KnownNat a) => MapHaar n ('(a,b) ': xs) where
maphaar sn _ = h : t
where l = map (\i -> fromIntegral i / fromIntegral (natVal
sn)) $ upto (undefined :: sing (ToNat n))
h = map (\x -> (x, unHaar (haar :: Haar a b) x)) l
t = maphaar sn (undefined :: sing xs)
data instance Sing 100 = S100
foo = maphaar S100 (undefined :: sing '[ '(1,1), '(2,1), '(2,3),
'(3,1), '(3,5), '(3,7)])
-----
Regards,
Marcin
More information about the Haskell-Cafe
mailing list