How can I turn a [TExp a] into a TExp [a], or otherwise apply refineTH to multiple values programatically? - haskell

I've been using refined for refinement types in Haskell recently, and have encountered a major usability problem. I can't figure out how to refine an entire list of values at compile time.
For example I can write:
{-# LANGUAGE TemplateHaskell #-}
import Refined
oneToThree :: [Refined Positive Int]
oneToThree = [$$(refineTH 1), $$(refineTH 2), $$(refineTH 3)]
But I can't do this precludes the ability of using range syntax, because Refined doesn't (for good reason) have an instance for Enum.
I would like to be able to do something like
oneToThree :: [Refined Positive Int]
oneToThree = $$(traverse refineTH [1..3])
but I can't get this to compile because I can't lift [TExp (Refined Positive Int)] into TExp [Refined Positive Int].
Is there template haskell magic that I missing that will let me do this?
Would also be open to suggestions for better lightweight refinement type libraries if someone has a suggestion.

sequenceQTExpList :: [Q (TExp a)] -> Q (TExp [a])
sequenceQTExpList [] = [|| [] ||]
sequenceQTExpList (x:xs) = [|| $$(x) : $$(sequenceQTExpList xs) ||]
Then use it as
$$(sequenceQTExpList $ map refineTH [1..3])
You're right that it feels like a traverse. The type is a bit off, though, with the extra Qs floating around. I don't see anything offhand that lets you combine those layers usefully.
Unfortunately, a lot of the mechanism used there is TH syntax rather than functions. There just isn't an obvious way to do both the lifting and the splicing as functions, so you're stuck writing bespoke helpers for each container type instead of getting to use Traversable. It's an interesting problem. If there's a clean solution, it'd have a good chance of making it into a future version of template Haskell if it was brought up to the maintainers. But I just don't see it right now.

This works (it needs to be in a different file than you use it in because of the stage restriction, though):
import Language.Haskell.TH.Syntax (Exp(ListE), TExp(TExp))
makeTypedTHList :: [TExp a] -> TExp [a]
makeTypedTHList xs = TExp $ ListE [x | TExp x <- xs]
You'd then use it like this:
{-# LANGUAGE TemplateHaskell #-}
import Refined
import AboveCodeInSeparateModuleBecauseOfStageRestriction (makeTypedTHList)
oneToThree :: [Refined Positive Int]
oneToThree = $$(makeTypedTHList <$> traverse refineTH [1..3])
However, calling the TExp constructor yourself subverts some of the safety of typed Template Haskell (although I think this particular case is safe). Ideally, I'd prefer an approach that didn't require doing that, but I can't think of one.

Related

is it possible to have a set comprehension in haskell?

In Haskell we have list generators, such as:
[x+y | x<-[1,2,3], y<-[1,2,3]]
with which we get
[2,3,4,3,4,5,4,5,6]
Is it possible to have a set generator which doesn't automatically add an element if it is already in the list?
In our example we would obtain:
[2,3,4,5,6]
If so, how? If it is not already implemented, how would you implement it?
Haskell can do this, but not quite out-of-the-box.
The basic underpinning is that a list comprehension can also be written as a monadic binding chain, in the list monad:
Prelude> [x+y | x<-[1,2,3], y<-[1,2,3]]
[2,3,4,3,4,5,4,5,6]
Prelude> [1,2,3] >>= \x -> [1,2,3] >>= \y -> return (x+y)
[2,3,4,3,4,5,4,5,6]
...or, with better readable do-syntax (which is syntactic sugar for monadic binding)
Prelude> do x<-[1,2,3]; y<-[1,2,3]; return (x+y)
[2,3,4,3,4,5,4,5,6]
In fact, there's a language extension that also turns all list comprehensions into syntactic sugar for such a monadic chain. Example in the tuple (aka writer) monad:
Prelude> :set -XMonadComprehensions
Prelude> [x+y | x <- ("Hello", 4), y <- ("World", 5)] :: (String, Int)
("HelloWorld",9)
So really, all we need is a set monad. This is sensible enough, however Data.Set.Set is not a monad on Hask (the category of all Haskell types) but only only the subcategory that satisfies the Ord constraint (which is needed for lookup / to avoid duplicates). In the case of sets, there is however a hack that allows hiding that constraint from the actual monad instance; it's used in the set-monad package. Et voilà:
Prelude Data.Set.Monad> [x+y | x<-fromList[1,2,3], y<-fromList[1,2,3]]
fromList [2,3,4,5,6]
The hack that's needed for instance Monad Set comes at a price. It works like this:
{-# LANGUAGE GADTs, RankNTypes #-}
import qualified Data.Set as DS
data Set r where
Prim :: (Ord r => DS.Set r) -> Set r
Return :: a -> Set a
Bind :: Set a -> (a -> Set b) -> Set b
...
What this means is: a value of type Data.Set.Monad.Set Int does not really contain a concrete set of integers. Rather, it contains an abstract syntax expression for a computation that yields a set as the result. This isn't great for performance, in particular it means that values won't be shared. So don't use this for big sets.
There's a better option: use it directly as a monad in the proper category (which only contains orderable types to begin with). This unfortunately requires even more language-bending, but it's possible; I've made an example in the constrained-categories library.
If your values can be put in Data.Set.Set (i.e. they are in class Ord) you can just apply Data.Set.toList . Data.Set.fromList to your list:
Prelude> import Data.Set
Prelude Data.Set> Data.Set.toList . Data.Set.fromList $ [x+y | x<-[1,2,3], y<-[1,2,3]]
[2,3,4,5,6]
The complexity of this would be O(n log n).
If the type obeys (Eq a, Hashable a), you can use Data.HashSet in much the same way. The average complexity is O(n).
If all you have is Eq, you have to get by with something like Data.List.nub:
Prelude> import Data.List
Prelude Data.List> nub [x+y | x<-[1,2,3], y<-[1,2,3]]
[2,3,4,5,6]
but the complexity is inherently quadratic.

Simple dependent type example in Haskell for Dummies. How are they useful in practice in Haskell? Why should I care about dependent types ?

I hear a lot about dependent types nowadays and I heard that DataKinds is somehow related to dependent typing (but I am not sure about this... just heard it on a Haskell Meetup).
Could someone illustrate with a super simple Haskell example what dependent typing is and what is it good for ?
On wikipedia it is written that dependent types can help prevent bugs. Could you give a simple example about how dependent types in Haskell can prevent bugs?
Something that I could start using in five minutes right now to prevent bugs in my Haskell code?
Dependent types are basically functions from values to types, how can this be used in practice? Why is that good ?
Late to the party, this answer is basically a shameless plug.
Sam Lindley and I wrote a paper about Hasochism, the pleasure and pain of dependently typed programming in Haskell. It gives plenty of examples of what's possible now in Haskell and draws points of comparison (favourable as well as not) with the Agda/Idris generation of dependently typed languages.
Although it is an academic paper, it is about actual programs, and you can grab the code from Sam's repo. We have lots of little examples (e.g. orderedness of mergesort output) but we end up with a text editor example, where we use indexing by width and height to manage screen geometry: we make sure that components are regular rectangles (vectors of vectors, not ragged lists of lists) and that they fit together exactly.
The key power of dependent types is to maintain consistency between separate data components (e.g., the head vector in a matrix and every vector in its tail must all have the same length). That's never more important than when writing conditional code. The situation (which will one day come to be seen as having been ridiculously naïve) is that the following are all type-preserving rewrites
if b then t else e => if b then e else t
if b then t else e => t
if b then t else e => e
Although we are presumably testing b because it gives us some useful insight into what would be appropriate (or even safe) to do next, none of that insight is mediated via the type system: the idea that b's truth justifies t and its falsity justifies e is missing, despite being critical.
Plain old Hindley-Milner does give us one means to ensure some consistency. Whenever we have a polymorphic function
f :: forall a. r[a] -> s[a] -> t[a]
we must instantiate a consistently: however the first argument fixes a, the second argument must play along, and we learn something useful about the result while we are at it. Allowing data at the type level is useful because some forms of consistency (e.g. lengths of things) are more readily expressed in terms of data (numbers).
But the real breakthrough is GADT pattern matching, where the type of a pattern can refine the type of the argument it matches. You have a vector of length n; you look to see whether it's nil or cons; now you know whether n is zero or not. This is a form of testing where the type of the code in each case is more specific than the type of the whole, because in each case something which has been learned is reflected at the type level. It is learning by testing which makes a language dependently typed, at least to some extent.
Here's a silly game to play, whatever typed language you use. Replace every type variable and every primitive type in your type expressions with 1 and evaluate types numerically (sum the sums, multiply the products, s -> t means t-to-the-s) and see what you get: if you get 0, you're a logician; if you get 1, you're a software engineer; if you get a power of 2, you're an electronic engineer; if you get infinity, you're a programmer. What's going on in this game is a crude attempt to measure the information we're managing and the choices our code must make. Our usual type systems are good at managing the "software engineering" aspects of coding: unpacking and plugging together components. But as soon as a choice has been made, there is no way for types to observe it, and as soon as there are choices to make, there is no way for types to guide us: non-dependent type systems approximate all values in a given type as the same. That's a pretty serious limitation on their use in bug prevention.
The common example is to encode the length of a list in it's type, so you can do things like (pseudo code).
cons :: a -> List a n -> List a (n+1)
Where n is an integer. This let you specify that adding an object to list increment its length by one.
You can then prevent head (which give you the first element of a list) to be ran on empty list
head :: n > 0 => List a n -> a
Or do things like
to3uple :: List a 3 -> (a,a,a)
The problem with this type of approach is you then can't call head on a arbitrary list without having proven first that the list is not null.
Sometime the proof can be done by the compiler, ex:
head (a `cons` l)
Otherwise, you have to do things like
if null list
then ...
else (head list)
Here it's safe to call head, because you are in the else branch and therefore guaranteed that the length is not null.
However, Haskell doesn't do dependent type at the moment, all the examples have given won't work as nicely, but you should be able to declare this type of list using DataKind because you can promote a int to type which allow to instanciate List a b with List Int 1. (b is a phantom type taking a literal).
If you are interested in this type of safety, you can have a look a liquid Haskell.
Here is a example of such code
{-# LANGUAGE DataKinds, KindSignatures, TypeFamilies, TypeOperators #-}
import GHC.TypeLits
data List a (n:: Nat) = List [a] deriving Show
cons :: a -> List a n -> List a (n + 1)
cons x (List xs) = List (x:xs)
singleton :: a -> List a 1
singleton x = List [x]
data NonEmpty
data EmptyList
type family ListLength a where
ListLength (List a 0) = EmptyList
ListLength (List a n) = NonEmpty
head' :: (ListLength (List a n) ~ NonEmpty) => List a n -> a
head' (List xs) = head xs
tail' :: (ListLength (List a n) ~ NonEmpty) => List a n -> List a (n-1)
tail' (List xs) = List (tail xs)
list = singleton "a"
head' list -- return "a"
Trying to do head' (tail' list) doesn't compile and give
Couldn't match type ‘EmptyList’ with ‘NonEmpty’
Expected type: NonEmpty
Actual type: ListLength (List [Char] 0)
In the expression: head' (tail' list)
In an equation for ‘it’: it = head' (tail' list)
Adding to #mb14's example, here's some simpler working code.
First, we need DataKinds, GADTs, and KindSignatures to really make it clear:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTS #-}
{-# LANGUAGE KindSignatures #-}
Now let's define a Nat type, and a Vector type based on it:
data Nat :: * where
Z :: Nat
S :: Nat -> Nat
data Vector :: Nat -> * -> * where
Nil :: Vector Z a
(:-:) :: a -> Vector n a -> Vector (S n) a
And voila, lists using dependent types that can be called safe in certain circumstances.
Here are the head and tail functions:
head' :: Vector (S n) a -> a
head' (a :-: _) = a
-- The other constructor, Nil, doesn't apply here because of the type signature!
tail' :: Vector (S n) a -> Vector n a
tail (_ :-: xs) = xs
-- Ditto here.
This is a more concrete and understandable example than above, but does the same sort of thing.
Note that in Haskell, Types can influence values, but values cannot influence types in the same dependent ways. There are languages such as Idris that are similar to Haskell but also support value-to-type dependent typing, which I would recommend looking into.
The machines package lets users define machines that can request values. Many machines request only one type of value, but it's also possible to define machines that sometimes ask for one type and sometimes ask for another type. The requests are values of a GADT type, which allows the value of the request to determine the type of the response.
Step k o r = ...
| forall t . Await (t -> r) (k t) r
The machine provides a request of type k t for some unspecified type t, and a function to deal with the result. By pattern matching on the request, the machine runner learns what type it must supply the machine. The machine's response handler doesn't need to check that it got the right sort of response.

StateT and non-determinism monad: a simple example

As part of learning how to work with StateT and the nondeterminism monad, I'd like to write a function which uses these to enumerate the partitions of an integer (while being allowed to reuse integers). For example, passing an argument of 4 should result in [[1,1,1,1],[1,1,2],[2,2],[1,3],[4]] (uniqueness doesn't matter, I'm more concerned with just getting to working code).
(Also, I'm aware that there's a recursive solution for generating partitions as well as dynamic programming and generating function based solutions for counting partitions - the purpose of this exercise is to construct a minimal working example that combines StateT and [].)
Here's my attempt that was designed to work on any input less than or equal to 5:
{-# LANGUAGE NoImplicitPrelude #-}
{-# OPTIONS_GHC -Wall #-}
import CorePrelude
import Control.Monad.State.Lazy
sumState :: StateT Int [] [Int]
sumState = do
m <- lift [1..5]
n <- get <* modify (-m+)
case compare n 0 of
LT -> mzero
EQ -> return [m]
GT -> fmap (n:) sumState
runner :: Int -> [([Int],Int)]
runner = runStateT sumState
I'm using runStateT rather than evalStateT to help with debugging (it's helpful to see the final state values). Like I said, I'm not too worried about generating unique partitions since I'd first like to just understand the correct way to use these two monads together.
Loading it in GHCi and evaluating runner 4 results in the following and I'm confused as to why the above code produces this output.
[([4,3,2,1,1],-1),([4,3,2,1,2],-2),([4,3,2,1,3],-3),([4,3,2,1,4],-4),([4,3,2,1,5],-5),([4,3,2,1],-1),([4,3,2,2],-2),([4,3,2,3],-3),([4,3,2,4],-4),([4,3,2,5],-5),([4,3,1,1],-1),([4,3,1,2],-2),([4,3,1,3],-3),([4,3,1,4],-4),([4,3,1,5],-5),([4,3,1],-1),([4,3,2],-2),([4,3,3],-3),([4,3,4],-4),([4,3,5],-5),([4,2,1,1],-1),([4,2,1,2],-2),([4,2,1,3],-3),([4,2,1,4],-4),([4,2,1,5],-5),([4,2,1],-1),([4,2,2],-2),([4,2,3],-3),([4,2,4],-4),([4,2,5],-5),([4,1,1],-1),([4,1,2],-2),([4,1,3],-3),([4,1,4],-4),([4,1,5],-5),([4,1],-1),([4,2],-2),([4,3],-3),([4,4],-4),([4,5],-5)]
What am I doing wrong? What's the correct way to combine StateT and [] in order to enumerate partitions?
You just have two little mistakes. The first is here:
n <- get <* modify (-m+)
This gets the value of n before we subtract m. You almost certainly want
n <- modify (-m+) >> get
instead, or
modify (-m+)
n <- get
if you prefer that spelling. The other is that you're putting the current state in the list instead of the value you're adding in the GT branch:
GT -> fmap (n:) sumState
Change that to
GT -> fmap (m:) sumState
and you're golden:
*Main> runner 4
[([1,1,1,1],0),([1,1,2],0),([1,2,1],0),([1,3],0),([2,1,1],0),([2,2],0),([3,1],0),([4],0)]

Couldn't match kind `*' against `#'

What the heck is going on here:
"Couldn't match kind `*' against `#'"
I was trying the following in GHCi using TemplateHaskell (ghci -XTemplateHaskell)
$(reify ''Show >>= dataToExpQ (const Nothing))
I was hoping to get an Exp out of this (which does have an instance of Show). I am doing this to insert information about haskell types in an application such that it is available as actual data, not as a string.
My goal is the following:
info :: Info
info = $(reify ''Show >>= dataToExpQ (const Nothing))
I really don't understand that error message, what is '#' anyway? If there is #, is there also # -> # or * -> #? Is it something that relates to kinds like kinds relate to types (though I would not know what that could be)?
Okay, so I do understand now that GHC has a hierarchy of kinds and that `#' is a special kind of unboxed types. All well and good, but why does this error pop up? Maybe unboxed types do not play well with genercis?
I'm not fully sure that this makes sense to me yet, since I would consider unboxed types being an optimazition performed by the compiler. I also thought that if an instance of Data exists, it needs to be there for all types that could possible be included in the data structure.
Upon further investigation I believe that Names pose the problem, is there a way to circumvent them in dataToExpQ? How to use that argument anyway?
You're right, it is the Names that cause the problem. More specifically, the problem is that the NameFlavour data type has unboxed integers in some of its fields.
There's a Haddock note on the Data NameFlavor instance that raises some red flags. And if you click through to the source, you'll see that the gfoldl definition essentially treats the unboxed integers like integers. (There's really not much else choice…) This ultimately causes the error you're seeing because dataToExpQ — having been tricked by the deceptive Data NameFlavour instance — builds an Exp term that applies NameU to an (Int :: *) when NameU actually expects an (unboxed) (Int# :: #).
So the problem is that the Data instance for NameFlavour disobeys the invariant assumed by dataToExpQ. But not to worry! This scenario falls squarely under the reason that dataToExpQ takes an argument: the argument lets us provide special treatment for troublesome types. Below, I do this in order to correctly reify the NameFlavour constructors that have unboxed integer fields.
There may be solutions out there for this, but I'm not aware of them, so I rolled up the following. It requires a separate module because of the TH staging restriction.
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MagicHash #-}
module Stage0 where
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import GHC.Types (Int(I#))
import GHC.Prim (Int#)
unboxed :: Int# -> Q Exp
unboxed i = litE $ intPrimL $ toInteger $ I# i -- TH does support unboxed literals
nameFlavorToQExp :: NameFlavour -> Maybe (Q Exp)
nameFlavorToQExp n = case n of
NameU i -> Just [| NameU $(unboxed i) |]
NameL i -> Just [| NameL $(unboxed i) |]
_ -> Nothing
And then the following compiles for me.
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Generics.SYB
import Stage0
info :: Info
info = $(reify ''Show >>= dataToExpQ (mkQ Nothing nameFlavorToQExp))
CAVEAT PROGRAMMER The unboxed integers we're bending over backwards for here correspond to "uniques" that GHC uses internally. They are not necessarily expected to be serialized. Depending on how you're using the resulting Info value, this may cause explosions.
Also note when reifying Show, you're also reifying every instance of Show that's in scope.
There's a lot of them — this generates a pretty big syntax term.
As the documentation says, these instances do not include the method definitions.
HTH.

Is a scoped type statement possible?

Is it possible to do the following:
foo = bar
where
type A = (Some, Huge, Type, Sig)
meh :: A -> (A, A) -> A
I only need to use this custom type inside the where clause, so it does not make sense to define it globally.
This isn't possible. Why not just define it above the function? You don't have to export it from the module (just use an explicit export list).
By the way, if you really do have a type that big, it's probably a sign that you should factor it into smaller parts, especially if you have a lot of tuples as your example suggests; data-types would be more appropriate.
Actually, there's one, slightly ridiculous, way to approximate this:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
foo :: forall abbrv. (abbrv ~ (Some, Huge, Type, Sig))
=> abbrv -> abbrv
foo x = meh x (x, x)
where meh :: abbrv -> (abbrv, abbrv) -> abbrv
meh x y = {- ... -}
I can't really recommend enabling two language extensions just for the sake of abbreviating types in signatures, though if you're already using them (or GADTs instead of type families) I suppose it doesn't really hurt anything.
Silliness aside, you should consider refactoring your types in cases like this, as ehird suggests.

Resources