[Haskell-cafe] type level Min function for GHC.TypeLits?
Baojun Wang
wangbj at gmail.com
Fri Jul 1 17:28:43 UTC 2016
Hi Cafe,
I'm trying to do some basic type level tricks, I wonder whether it is
possible to get ``vZipWith`` in below code snippet working:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}
import GHC.TypeLits
import Data.Proxy
data Vect :: (Nat -> * -> *) where
VNil :: Vect 0 a
VCons :: a -> Vect n a -> Vect (1+n) a
deriving instance (Show a) => Show (Vect n a)
vlength :: forall n a . KnownNat n => Vect n a -> Integer
vlength _ = natVal (Proxy :: Proxy n)
vconcat :: Vect n a -> Vect m a -> Vect (n+m) a -- Need type
checker plugin
vconcat VNil ys = ys
vconcat xs VNil = xs
vconcat (VCons x xs) ys = VCons x (vconcat xs ys)
type family Min3 (t :: Bool) (m :: Nat) (n :: Nat) :: Nat
type instance Min3 'True m n = m
type instance Min3 'False m n = n
type Min m n = Min3 (m <=? n) m n
vZipWith :: (a -> b -> c) -> Vect m a -> Vect n b -> Vect (Min m n) c
vZipWith f VNil _ = VNil
vZipWith f _ VNil = VNil
vZipWith f (VCons x xs) (VCons y ys) = f x y `VCons` vZipWith f xs ys
As I got errors:
/home/wangbj/downloads/stack/vect/src/Vect.hs:51:21:
Could not deduce (Min3 (m <=? 0) m 0 ~ 0)
from the context (n ~ 0)
bound by a pattern with constructor
VNil :: forall a. Vect 0 a,
in an equation for ‘vZipWith’
at /home/wangbj/downloads/stack/vect/src/Vect.hs:51:14-17
Expected type: Vect (Min m n) c
Actual type: Vect 0 c
Relevant bindings include
vZipWith :: (a -> b -> c)
-> Vect m a -> Vect n b -> Vect (Min m n) c
(bound at /home/wangbj/downloads/stack/vect/src/Vect.hs:50:1)
In the expression: VNil
In an equation for ‘vZipWith’: vZipWith f _ VNil = VNil
/home/wangbj/downloads/stack/vect/src/Vect.hs:52:40:
Could not deduce (Min3 (m <=? n) m n
~ (1 + Min3 (n1 <=? n2) n1 n2))
from the context (m ~ (1 + n1))
bound by a pattern with constructor
VCons :: forall a (n :: Nat). a -> Vect n a -> Vect (1 +
n) a,
in an equation for ‘vZipWith’
at /home/wangbj/downloads/stack/vect/src/Vect.hs:52:13-22
or from (n ~ (1 + n2))
bound by a pattern with constructor
VCons :: forall a (n :: Nat). a -> Vect n a -> Vect (1 +
n) a,
in an equation for ‘vZipWith’
at /home/wangbj/downloads/stack/vect/src/Vect.hs:52:26-35
Expected type: Vect (Min m n) c
Actual type: Vect (1 + Min n1 n2) c
Relevant bindings include
ys :: Vect n2 b
(bound at /home/wangbj/downloads/stack/vect/src/Vect.hs:52:34)
xs :: Vect n1 a
(bound at /home/wangbj/downloads/stack/vect/src/Vect.hs:52:21)
vZipWith :: (a -> b -> c)
-> Vect m a -> Vect n b -> Vect (Min m n) c
(bound at /home/wangbj/downloads/stack/vect/src/Vect.hs:50:1)
In the expression: f x y `VCons` vZipWith f xs ys
In an equation for ‘vZipWith’:
vZipWith f (VCons x xs) (VCons y ys)
= f x y `VCons` vZipWith f xs ys
Failed, modules loaded: none.
Also I tried https://github.com/yav/type-nat-solver but got error like:
*** Exception: user error (Unexpected result from the SMT solver:
Expected: success
Result: (error "line 57 column 16: unknown constant tn_0" )
Which I have no idea what it really means.
Is there any way to get ``vZipWith`` working without too much hassle?
Thanks
baojun
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20160701/7089def8/attachment.html>
More information about the Haskell-Cafe
mailing list