[Haskell-cafe] Runtime selection on types while capturing a dictionary?

Tom Ellis tom-lists-haskell-cafe-2023 at jaguarpaw.co.uk
Mon Oct 7 22:13:43 UTC 2024


On Mon, Oct 07, 2024 at 05:38:30PM -0400, Benjamin Redelings wrote:
> I'm new to Haskell, and I'm writing a class for evolutionary trees.  Since
> I'm new to Haskell, trying to encode information at the type level is new to
> me.  In C++ I'd use runtime checks to ask whether (for example) a tree is
> rooted.  Or I'd have the getRoot function return Maybe NodeID and then make
> the methods for checking if a branch points rootward throw an exception if
> the tree is unrooted.

I think I'd just do

    data AugmentedTree roots lengths labels =
      MkAugmentedTree {
        tree :: Tree,
        labels :: labels,
        roots :: roots,
        lengths :: lenghts
      }

and then just do stuff like

    type FullyAugmentedTree =
        AugmentedTree [NodeId] (IntMap Double) (IntMap (Maybe l))
 
    type PartiallyAugmentedTree = 
        AugmentedTree [NodeId] () (IntMap (Maybe l))

For rootedness-independence I strongly recommend against any type
class shenanigans.  Instead you can do

    data PossiblyRootedTree lengths labels where
        RootedTree :: AugmentedTree [NodeId] lengths labels
        UnrootedTree :: AugmentedTree () lengths labels

and then

    isRooted :: PossiblyRootedTree lengths labels -> Bool
    isRooted = \case
       RootedTree {} -> True
       UnrootedTree {} -> False

(but `isRooted` is not really very useful compared to just pattern
matching every where you need to know.)

Tom


More information about the Haskell-Cafe mailing list