Using haskell's singletons, how can I write `fromList :: [a] -> Vec a n`?

后端 未结 2 1900
离开以前
离开以前 2020-12-19 14:11

As part of my journey in understanding singletons I have tried to bridge the gap between compile time safety, and lifting runtime values into that dependent typ

2条回答
  •  情歌与酒
    2020-12-19 14:49

    This is not possible using Haskell because Haskell does not yet have full dependent types (although GHC might in the future). Notice that

    fromList :: [a] -> Vec a n
    

    Has both a and n quantified universally, which means that the user should be able to pick their n and get back a Vec of the right size. That makes no sense! The trick is that n is not really for the user to choose - it has to be the length of the input list. (For the same reason, fromList :: Integer -> [a] -> Vec a n would not be any more useful - the size hint has to be something type-level.)

    Looking to a dependently typed language like Idris, you can define

    fromList : (l : List elem) -> Vec (length l) elem
    

    And in fact they define this in the standard library.

    So, what can you do? Short of saying that Vec has the length equal to the size of the input list (which requires lifting "length of the input list" to the type level), you can say it has some length.

    data SomeVec a where { SomeVec :: Vec a n -> SomeVec a }
    
    list2SomeVec :: [a] -> SomeVec a
    list2SomeVec [] = SomeVec Nil
    list2SomeVec (x:xs) = case list2SomeVec xs of
                            SomeVec ys -> SomeVec (x `Cons` ys)
    

    That isn't spectacularly useful, but it is better than nothing.

提交回复
热议问题