Skip to content

Instantly share code, notes, and snippets.

@ChrisPenner
Created November 18, 2020 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ChrisPenner/cef35c3b8db9b945084c30ade437e337 to your computer and use it in GitHub Desktop.
Save ChrisPenner/cef35c3b8db9b945084c30ade437e337 to your computer and use it in GitHub Desktop.
A hack to require type applications, even when not necessary
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
-- Don't export this, it's just to make it so the type family *could* have a different
-- result, even though it never will!
data Never
type family Identity a where
Identity Never = ()
Identity a = a
-- Set up the instance
class From a b where
from :: a -> b
instance From a [a] where
from = pure
-- The type fam makes (Identity b) ambigous until applied, even though `Identity b ~ b` always.
into :: forall b a. (From a (Identity b)) => a -> Identity b
into = from
-- This expression fails to compile without the type application
use :: String
use = into @String 'a'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment