Search code examples
c++haskelltemplate-specializationcompile-timestatic-typing

Can C++ pattern of making structs to 'correspond' types be emulated in Haskell (template specialization)?


template <typename T>
struct Corresponding;

template <>
struct Corresponding<int> {
    using CorrespondingT = boost::multiprecison::cpp_int;
};
template <typename T> using GetCorresponding = typename Corresponding<T>::CorrespondingT;

This can be used as

static_assert(std::is_same_v<GetCorresponding<int>, boost::multiprecision::cpp_int>); // true

Where Corresponding<T> is the struct containing an alias with a corresponding type of T, resolved at compile-time. Another example of this is std::remove_ptr_t<T*> which corresponds to T

Can I do something similar in Haskell, e.g.

iAmAnInteger :: getCorresponding Int -- Integer

?

I'm not familiar Haskell's capabilities with compile-time types but is this possible?


Solution

  • I'm not fluent in C++, so I'm not 100% sure what your example code is doing, but at a first glance type families and equalities seem similar.

    {-# LANGUAGE TypeFamilies #-}
    
    type family Corresponding a
    type instance Corresponding Int = Integer
    
    foo :: Corresponding Int ~ Integer => ()
    foo = () -- compiles
    
    bar :: Corresponding Int ~ Bool => ()
    bar = () -- type error at any use site
    
    baz :: Corresponding Int
    baz = toInteger 3 -- compiles
    
    quux :: Corresponding Int
    quux = False -- type error