How do I implement this function without using mixed lists? - haskell

Let's say I have a function that takes a list of function-list pairs, and maps the function in each pair onto the list in the pair, for example:
myFunction [("SOME"++,["DAY","ONE"]), (show,[1,2])] == [["SOMEDAY", "SOMEONE"],["1","2"]]
Is there a way of implementing myFunction so that the code I provided above will work as is without any modifications?
My problem is I can't figure out how to implement myFunction because the types of each sub-list could be different (in my example I have a list of strings ["DAY", ONE"], and a list of numbers: [1,2]). I know that each function in the list will convert its list into a list of strings (so the final list will have type [[Char]]), but I don't know how to express this in Haskell.

You can do it with existential types
{-# LANGUAGE ExistentialQuantification #-}
data T = forall a b. Show b => (:?:) (a -> b) [a]
table =
[ ("SOME"++) :?: ["DAY","ONE"]
, (show) :?: [1,2]
, (+1) :?: [2.9, pi]
]
And run it as:
apply :: T -> String
apply (f :?: xs) = show $ map f xs
main = print $ map apply table

You want to use existential quantification to define a type that can hold any value as long as it is a member of the Show typeclass. For example:
{-# LANGUAGE ExistentialQuantification #-}
data S = forall a. Show a => S a
instance Show S where
show (S s) = show s
f :: [S] -> [String]
f xs = map show xs
And now in ghci:
*Main> f [S 1, S True, S 'c']
["1","True","'c'"]
You won't be able to run the code in your question without modification, because it contains a heterogeneous list, which the Haskell type system forbids. Instead you can wrap heterogeneous types up as a variant type (if you know in advance all the types that will be required) or as an existentially quantified type (if you don't know what types will be required, but you do know a property that they must satisfy).

Related

Error matching types: using MultiParamTypeClasses and FunctionalDependencies to define heterogeneous lists and a function that returns first element

There is a relevant question concerning Functional Dependencies used with GADTs. It turns out that the problem is not using those two together, since similar problems arise without the use of GADTs. The question is not definitively answered, and there is a debate in the comments.
The problem
I am trying to make a heterogeneous list type which contains its length in the type (sort of like a tuple), and I am having a compiling error when I define the function "first" that returns the first element of the list (code below). I do not understand what it could be, since the tests I have done have the expected outcomes.
I am a mathematician, and a beginner to programming and Haskell.
The code
I am using the following language extensions:
{-# LANGUAGE GADTs, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
First, I defined natural numbers in the type level:
data Zero = Zero
newtype S n = S n
class TInt i
instance TInt Zero
instance (TInt i) => TInt (S i)
Then, I defined a heterogeneous list type, along with a type class that provides the type of the first element:
data HList a as where
EmptyList :: HList a as
HLCons :: a -> HList b bs -> HList a (HList b bs)
class First list a | list -> a
instance First (HList a as) a
And finally, I defined the Tuple type:
data Tuple list length where
EmptyTuple :: Tuple a Zero
TCons :: (TInt length) => a -> Tuple list length -> Tuple (HList a list) (S length)
I wanted to have the function:
first :: (First list a) => Tuple list length -> a
first EmptyTuple = error "first: empty Tuple"
first (TCons x _) = x
but it does not compile, with a long error that appears to be that it cannot match the type of x with a.
Could not deduce: a1 ~ a
from the context: (list ~ HList a1 list1, length ~ S length1,
TInt length1)
bound by a pattern with constructor:
TCons :: forall length a list.
TInt length =>
a -> Tuple list length -> Tuple (HList a list) (S length),
in an equation for ‘first’
[...]
Relevant bindings include
x :: a1 (bound at problem.hs:26:14)
first :: Tuple list length -> a (bound at problem.hs:25:1)
The testing
I have tested the type class First by defining:
testFirst :: (First list a) => Tuple list length -> a
testFirst = undefined
and checking the type of (testFirst x). For example:
ghci> x = TCons 'a' (TCons 5 (TCons "lalala" EmptyTuple))
ghci> :t (testFirst x)
(testFirst x) :: Char
Also this works as you would expect:
testMatching :: (Tuple (HList a as) n) -> a
testMatching (TCons x _) = x
"first" is basically these two combined.
The question
Am I attempting to do something the language does not support (maybe?), or have I stumbled on a bug (unlikely), or something else (most likely)?
Oh dear, oh dear. You have got yourself in a tangle. I imagine you've had to battle through several perplexing error messages to get this far. For a (non-mathematician) programmer, there would have been several alarm bells hinting it shouldn't be this complicated. I'll 'patch up' what you've got now; then try to unwind some of the iffy code.
The correction is a one-line change. The signature for first s/b:
first :: Tuple (HList a as) length -> a
As you figured out in your testing. Your testFirst only appeared to make the right inference because the equation didn't try to probe inside a GADT. So no, that's not comparable.
There's a code 'smell' (as us humble coders call it): your class First has only one instance -- and I can't see any reason it would have more than one. So just throw it away. All I've done with the signature for first is put the list's type from the First instance head direct into the signature.
Explanation
Suppose you wrote the equations for first without giving a signature. That gets rejected blah rigid type variable bound by a pattern with constructor ... blah. Yes GHC's error messages are completely baffling. What it means is that the LHS of first's equations pattern match on a GADT constructor -- TCons, and any constraints/types bound into it cannot 'escape' the pattern match.
We need to expose the types inside TCons in order to let the type pattern-matched to variable x escape. So TCons isn't binding just any old list; it's specifically binding something of the form (HList a as).
Your class First and its functional dependency was attempting to drive that typing inside the pattern match. But GADTs have been maliciously designed to not co-operate with FunDeps, so that just doesn't work. (Search SO for '[haskell] functional dependency GADT' if you want to be more baffled.)
What would work is putting an Associated Type inside class First; or building a stand-alone 'type family'. But I'm going to avoid leading a novice into advanced features.
Type Tuple not needed
As #JonPurdy points out, the 'spine' of your HList type -- that is, the nesting of HLConss is doing just the same job as the 'spine' of your TInt data structure -- that is, the nesting of Ss. If you want to know the length of an HList, just count the number of HLCons.
So also throw away Tuple and TInt and all that gubbins. Write first to apply to an HList. (Then it's a useful exercise to write a length-indexed access: nth element of an HList -- not forgetting to fail gracefully if the index points beyond its end.)
I'd avoid the advanced features #Jon talks about, until you've got your arms around GADTs. (It's perfectly possible to program over heterogeneous lists without using GADTs -- as did the pioneers around 2003, but I won't take you backwards.)
I was trying to figure out how to do "calculations" on the type level, there are more things I'd like to implement.
Ok ... My earlier answer was trying to make minimal changes to get your code going. There's quite a bit of duplication/unnecessary baggage in your O.P. In particular:
Both HList and Tuple have constructors for empty lists (also length Zero means empty list). Furthermore both those Emptys allege there's a type (variable) for the head and the tail of those empty (non-)lists.
Because you've used constructors to denote empty, you can't catch at the type level attempts to extract the first of an empty list. You've ended up with a partial function that calls error at run time. Better is to be able to trap first of an empty list at compile time, by rejecting the program.
You want to experiment with FunDeps for obtaining the type of the first (and presumably other elements). Ok then to be type-safe, prevent there being an instance of the class that alleges the non-existent head of an empty has some type.
I still want to have the length as part of the type, it is the whole point of my type.
Then let's express that more directly (I'll use fresh names here, to avoid clashes with your existing code.) (I'm going to need some further extensions, I'll explain those at the end.):
data HTuple list length where
MkHTuple :: (HHList list, TInt length) => list -> length -> HTuple list length
This is a GADT with a single constructor to pair the list with its length. TInt length and types Zero, S n are as you have already. With HHList I've followed a similar structure.
data HNil = HNil deriving (Eq, Show)
data HCons a as = HCons a as deriving (Eq, Show)
class HHList l
instance HHList HNil
instance HHList (HCons a as)
class (HHList list) => HFirst list a | list -> a where hfirst :: list -> a
-- no instance HFirst HNil -- then attempts to call hfirst will be type error
instance HFirst (HCons a as) a where hfirst (HCons x xs) = x
HNil, HCons are regular datatypes, so we can derive useful classes for them. Class HHList groups the two datatypes, as you've done with TInt.
HFirst with its FunDep for the head of an HHList then works smoothly. And no instance HFirst HNil because HNil doesn't have a first. Note that HFirst has a superclass constraint (HHList list) =>, saying that HFirst applies only for HHLists.
We'd like HTuple to be Eqable and Showable. Because it's a GADT, we must go a little around the houses:
{-# LANGUAGE StandaloneDeriving #-}
deriving instance (Eq list, Eq length) => Eq (HTuple list length)
deriving instance (Show list, Show length) => Show (HTuple list length)
Here's a couple of sample tuples; and a function to get the first element, going via the HFirst class and its method:
htEmpty = MkHTuple HNil Zero
htup1 = MkHTuple (HCons (1 :: Int) HNil) (S Zero)
tfirst :: (HFirst list a) => HTuple list length -> a -- using the FunDep
tfirst (MkHTuple list length) = hfirst list
-- > :set -XFlexibleContexts -- need this in your session
-- > tfirst htup1 ===> 1
-- > tfirst htEmpty ===> error: No instance for (HFirst HNil ...
But you don't want to be building tuples with all those explicit constructors. Ok, we could define a cons-like function:
thCons x (MkHTuple li le) = MkHTuple (HCons x li) (S le)
htup2 = thCons "Two" htup1
But that doesn't look like a constructor. Furthermore you really (I suspect) want something to both construct and destruct (pattern-match) a tuple into a head and a tail. Then welcome to PatternSynonyms (and I'm afraid quite a bit of ugly declaration syntax, so the rest of your code can be beautiful). I'll put the beautiful bits first: THCons looks just like a constructor; you can nest multiple calls; you can pattern match to get the first element.
htupA = THCons 'A' THEmpty
htup3 = THCons True $ THCons "bB" $ htupA
htfirst (THCons x xs) = x
-- > htfirst htup3 ===> True
{-# LANGUAGE PatternSynonyms, ViewPatterns, LambdaCase #-}
pattern THEmpty = MkHTuple HNil Zero -- simple pattern, spelled upper-case like a constructor
-- now the ugly
pattern THCons :: (HHList list, TInt length)
=> a -> HTuple list length -> HTuple (HCons a list) (S length)
pattern THCons x tup <- ((\case
{ (MkHTuple (HCons x li) (S le) )
-> (x, (MkHTuple li le)) } )
-> (x, tup) )
where
THCons x (MkHTuple li le) = MkHTuple (HCons x li) (S le)
Look first at the last line (below the where) -- it's just the same as for function thCons, but spelled upper case. The signature (two lines starting pattern THCons ::) is as inferred for thCons; but with explicit class constraints -- to make sure we can build a HTuple only from valid components; which we need to have guaranteed when deconstructing the tuple to get its head and a properly formed tuple for the rest -- which is all that ugly code in the middle.
Question to the floor: can that pattern decl be made less ugly?
I won't try to explain the ugly code; read ViewPatterns in the User Guide. That's the last -> just above the where.

What's a better way of managing large Haskell records?

Replacing fields names with letters, I have cases like this:
data Foo = Foo { a :: Maybe ...
, b :: [...]
, c :: Maybe ...
, ... for a lot more fields ...
} deriving (Show, Eq, Ord)
instance Writer Foo where
write x = maybeWrite a ++
listWrite b ++
maybeWrite c ++
... for a lot more fields ...
parser = permute (Foo
<$?> (Nothing, Just `liftM` aParser)
<|?> ([], bParser)
<|?> (Nothing, Just `liftM` cParser)
... for a lot more fields ...
-- this is particularly hideous
foldl1 merge [foo1, foo2, ...]
merge (Foo a b c ...seriously a lot more...)
(Foo a' b' c' ...) =
Foo (max a a') (b ++ b') (max c c') ...
What techniques would allow me to better manage this growth?
In a perfect world a, b, and c would all be the same type so I could keep them in a list, but they can be many different types. I'm particularly interested in any way to fold the records without needing the massive patterns.
I'm using this large record to hold the different types resulting from permutation parsing the vCard format.
Update
I've implemented both the generics and the foldl approaches suggested below. They both work, and they both reduce three large field lists to one.
Datatype-generic programming techniques can be used to transform all the fields of a record in some "uniform" sort of way.
Perhaps all the fields in the record implement some typeclass that we want to use (the typical example is Show). Or perhaps we have another record of "similar" shape that contains functions, and we want to apply each function to the corresponding field of the original record.
For these kinds of uses, the generics-sop library is a good option. It expands the default Generics functionality of GHC with extra type-level machinery that provides analogues of functions like sequence or ap, but which work over all the fields of a record.
Using generics-sop, I tried to create a slightly less verbose version of your merge funtion. Some preliminary imports:
{-# language TypeOperators #-}
{-# language DeriveGeneric #-}
{-# language TypeFamilies #-}
{-# language DataKinds #-}
import Control.Applicative (liftA2)
import qualified GHC.Generics as GHC
import Generics.SOP
A helper function that lifts a binary operation to a form useable by the functions of generics-sop:
fn_2' :: (a -> a -> a) -> (I -.-> (I -.-> I)) a -- I is simply an Identity functor
fn_2' = fn_2 . liftA2
A general merge function that takes a vector of operators and works on any single-constructor record that derives Generic:
merge :: (Generic a, Code a ~ '[ xs ]) => NP (I -.-> (I -.-> I)) xs -> a -> a -> a
merge funcs reg1 reg2 =
case (from reg1, from reg2) of
(SOP (Z np1), SOP (Z np2)) ->
let npResult = funcs `hap` np1 `hap` np2
in to (SOP (Z npResult))
Code is a type family that returns a type-level list of lists describing the structure of a datatype. The outer list is for constructors, the inner lists contain the types of the fields for each constructor.
The Code a ~ '[ xs ] part of the constraint says "the datatype can only have one constructor" by requiring the outer list to have exactly one element.
The (SOP (Z _) pattern matches extract the (heterogeneus) vector of field values from the record's generic representation. SOP stands for "sum-of-products".
A concrete example:
data Person = Person
{
name :: String
, age :: Int
} deriving (Show,GHC.Generic)
instance Generic Person -- this Generic is from generics-sop
mergePerson :: Person -> Person -> Person
mergePerson = merge (fn_2' (++) :* fn_2' (+) :* Nil)
The Nil and :* constructors are used to build the vector of operators (the type is called NP, from n-ary product). If the vector doesn't match the number of fields in the record, the program won't compile.
Update. Given that the types in your record are highly uniform, an alternative way of creating the vector of operations is to define instances of an auxiliary typeclass for each field type, and then use the hcpure function:
class Mergeable a where
mergeFunc :: a -> a -> a
instance Mergeable String where
mergeFunc = (++)
instance Mergeable Int where
mergeFunc = (+)
mergePerson :: Person -> Person -> Person
mergePerson = merge (hcpure (Proxy :: Proxy Mergeable) (fn_2' mergeFunc))
The hcliftA2 function (that combines hcpure, fn_2 and hap) could be used to simplify things further.
Some suggestions:
(1) You can use the RecordWildCards extension to automatically
unpack a record into variables. Doesn't help if you need to unpack
two records of the same type, but it's a useful to keep in mind.
Oliver Charles has a nice blog post on it: (link)
(2) It appears your example application is performing a fold over the records.
Have a look at Gabriel Gonzalez's foldl package. There is also a blog post: (link)
Here is a example of how you might use it with a record like:
data Foo = Foo { _a :: Int, _b :: String }
The following code computes the maximum of the _a fields and the
concatenation of the _b_ fields.
import qualified Control.Foldl as L
import Data.Profunctor
data Foo = Foo { _a :: Int, _b :: String }
deriving (Show)
fold_a :: L.Fold Foo Int
fold_a = lmap _a (L.Fold max 0 id)
fold_b :: L.Fold Foo String
fold_b = lmap _b (L.Fold (++) "" id)
fold_foos :: L.Fold Foo Foo
fold_foos = Foo <$> fold_a <*> fold_b
theFoos = [ Foo 1 "a", Foo 3 "b", Foo 2 "c" ]
test = L.fold fold_foos theFoos
Note the use of the Profunctor function lmap to extract out
the fields we want to fold over. The expression:
L.Fold max 0 id
is a fold over a list of Ints (or any Num instance), and therefore:
lmap _a (L.Fold max 0 id)
is the same fold but over a list of Foo records where we use _a
to produce the Ints.

Couldn't match expected type in Haskell code that print nested list?

Here is my function
data Item a = One a | Many [Item a]
let flat (One x) = show x
let flat (Many xs) = show xs
Here is the output
Prelude> flat [[3]]
<interactive>:21:6:
Couldn't match expected type ‘Item t0’ with actual type ‘[[t1]]’
In the first argument of ‘flat’, namely ‘[[3]]’
In the expression: flat [[3]]
In an equation for ‘it’: it = flat [[3]]
It seems like flat doesn't recognize Item as its function signature so I tried redefine the function signature
flat :: Item a -> [a]
<interactive>:22:1:
Couldn't match type ‘a1’ with ‘Char’
‘a1’ is a rigid type variable bound by
an expression type signature: Item a1 -> [a1] at <interactive>:22:1
Expected type: Item a1 -> [a1]
Actual type: Item a1 -> String
In the expression: flat :: Item a -> [a]
In an equation for ‘it’: it = flat :: Item a -> [a]
But Haskell does not let you redefine function signature in ghci, is there a way around this?
flat [[3]] yields a type error. [[3]] has type Num a => [[a]], not Show a => Item a that you can pass into flat.
flat (Many [3]) will return "[3]".
Answering a follow-up question you asked in the comments of #jtobin's answer: yes there is a way to automatically dectect that [3] needs to be wrapped into a Maybe constructor. However you'll probably need to add type annotations (cf. example to help Haskell figure out what to do=.
We start with a bunch of language extensions.
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
Then comes your definition of Item.
module Item where
data Item a = One a | Many [Item a]
We introduce a class of things which may be reified to an Item a and declare two instances: the Many one and the base case. You can see that we now have overlapping instances (e.g. for Itemable [Int] [Int]) so you're playing with fire here.
class Itemable b a where
item :: b -> Item a
instance Itemable b a => Itemable [b] a where
item = Many . fmap item
instance Itemable a a where
item = One
You can finally define flat as a function that turns a b into an Item a first and then flattens it:
flat :: Itemable b a => b -> [a]
flat = go . item where
go (One a) = [a]
go (Many as) = concatMap go as
Which works as the following example typechecking and evaluating to [2,43,7,8,1] shows:
example :: [Int]
example = flat [[[[[[2::Int],[43]],[[7],[8]],[[1]]]]]]
However, as soon as you try to use the overlapping instances it'll blow in your face. E.g.:
example' :: [[Int]]
example' = flat [[[[[[2::Int],[43]],[[7],[8]],[[1]]]]]]

Is it possible to define a list recursively in Haskell?

In several programming languages (including JavaScript, Python, and Ruby), it's possible to place a list inside itself, which can be useful when using lists to represent infinitely-detailed fractals. However, I tried doing this in Haskell, and it did not work as I expected:
--aList!!0!!0!!1 should be 1, since aList is recursively defined: the first element of aList is aList.
main = putStrLn $ show $ aList!!0!!0!!1
aList = [aList, 1]
Instead of printing 1, the program produced this compiler error:
[1 of 1] Compiling Main ( prog.hs, prog.o )
prog.hs:3:12:
Occurs check: cannot construct the infinite type: t0 = [t0]
In the expression: aList
In the expression: [aList, 1]
In an equation for `aList': aList = [aList, 1]
Is it possible to put an list inside itself in Haskell, as I'm attempting to do here?
No, you can't. First off, there's a slight terminological confusion: what you have there are lists, not arrays (which Haskell also has) , although the point stands either way. So then, as with all things Haskell, you must ask yourself: what would the type of aList = [aList, 1] be?
Let's consider the simpler case of aList = [aList]. We know that aList must be a list of something, so aList :: [α] for some type α. What's α? As the type of the list elements, we know that α must be the type of aList; that is, α ~ [α], where ~ represents type equality. So α ~ [α] ~ [[α]] ~ [[[α]]] ~ ⋯ ~ [⋯[α]⋯] ~ ⋯. This is, indeed, an infinite type, and Haskell forbids such things.
In the case of the value aList = [aList, 1], you also have the restriction that 1 :: α, but all that that lets us conclude is that there must be a Num α constraint (Num α => [⋯[α]⋯]), which doesn't change anything.
The obvious next three questions are:
Why do Haskell lists only contain one type of element?
Why does Haskell forbid infinite types?
What can I do about this?
Let's tackle those in order.
Number one: Why do Haskell lists only contain one type of element? This is because of Haskell's type system. Suppose you have a list of values of different types: [False,1,2.0,'c']. What's the type of the function someElement n = [False,1,2.0,'c'] !! n? There isn't one, because you couldn't know what type you'd get back. So what could you do with that value, anyway? You don't know anything about it, after all!
Number two: Why does Haskell forbid infinite types? The problem with infinite types is that they don't add many capabilities (you can always wrap them in a new type; see below), and they make some genuine bugs type-check. For example, in the question "Why does this Haskell code produce the ‘infinite type’ error?", the non-existence of infinite types precluded a buggy implementation of intersperse (and would have even without the explicit type signature).
Number three: What can I do about this? If you want to fake an infinite type in Haskell, you must use a recursive data type. The data type prevents the type from having a truly infinite expansion, and the explicitness avoids the accidental bugs mentioned above. So we can define a newtype for an infinitely nested list as follows:
Prelude> newtype INL a = MkINL [INL a] deriving Show
Prelude> let aList = MkINL [aList]
Prelude> :t aList
aList :: INL a
Prelude> aList
MkINL [MkINL [MkINL [MkINL ^CInterrupted.
This got us our infinitely-nested list that we wanted—printing it out is never going to terminate—but none of the types were infinite. (INL a is isomorphic to [INL a], but it's not equal to it. If you're curious about this, the difference is between isorecursive types (what Haskell has) and equirecursive types (which allow infinite types).)
But note that this type isn't very useful; the only lists it contains are either infinitely nested things like aList, or variously nested collections of the empty list. There's no way to get a base case of a value of type a into one of the lists:
Prelude> MkINL [()]
<interactive>:15:8:
Couldn't match expected type `INL a0' with actual type `()'
In the expression: ()
In the first argument of `MkINL', namely `[()]'
In the expression: MkINL [()]
So the list you want is an arbitrarily nested list. The 99 Haskell Problems has a question about these, which requires defining a new data type:
data NestedList a = Elem a | List [NestedList a]
Every element of NestedList a is either a plain value of type a, or a list of more NestedList as. (This is the same thing as an arbitrarily-branching tree which only stores data in its leaves.) Then you have
Prelude> data NestedList a = Elem a | List [NestedList a] deriving Show
Prelude> let aList = List [aList, Elem 1]
Prelude> :t aList
aList :: NestedList Integer
Prelude> aList
List [List [List [List ^CInterrupted.
You'll have to define your own lookup function now, and note that it will probably have type NestedList a -> Int -> Maybe (NestedList a)—the Maybe is for dealing with out-of-range integers, but the important part is that it can't just return an a. After all, aList ! 0 is not an integer!
Yes. If you want a value that contains itself, you'll need a type that contains itself. This is no problem; for example, you might like rose trees, defined roughly like this in Data.Tree:
data Tree a = Node a [Tree a]
Now we can write:
recursiveTree = Node 1 [recursiveTree]
This isn't possible with the list type in Haskell, since each element has to be of the same type, but you could create a data type to do it. I'm not exactly sure why you'd want to, though.
data Nested a
= Value a
| List [Nested a]
deriving (Eq, Show)
nested :: Nested Int
nested = List [nested, Value 1]
(!) :: Nested a -> Int -> Nested a
(!) (Value _) _ = undefined
(!) (List xs) n = xs !! n
main = print $ nested ! 0 ! 0 ! 1
This will print out Value 1, and this structure could be of some use, but I'd imagine it's pretty limited.
There were several answers from "yes you can" to "no you absolutely cannot". Well, both are right, because all of them address different aspects of your question.
One other way to add "array" to itself, is permit a list of anything.
{-# LANGUAGE ExistentialQuantification #-}
data T = forall a. T a
arr :: [T]
arr = [T arr, T 1]
So, this adds arr to itself, but you cannot do anything else with it, except prove it is a valid construct and compile it.
Since Haskell is strongly typed, accessing list elements gives you T, and you could extract the contained value. But what is the type of that value? It is "forall a. a" - can be any type, which in essence means there are no functions at all that can do anything with it, not even print, because that would require a function that can convert any type a to String. Note that this is not specific to Haskell - even in dynamic languages the problem exists; there is no way to figure out the type of arr !! 1, you only assume it is a Int. What makes Haskell different to that other language, is that it does not let you use the function unless you can explain the type of the expression.
Other examples here define inductive types, which is not exactly what you are asking about, but they show the tractable treatment of self-referencing.
And here is how you could actually make a sensible construct:
{-# LANGUAGE ExistentialQuantification #-}
data T = forall a. Show a => T a
instance Show T where -- this also makes Show [T],
-- because Show a => Show [a] is defined in standard library
show (T x) = show x
arr :: [T]
arr = [T arr, T 1]
main = print $ arr !! 1
Now the inner value wrapped by T is restricted to be any instance of Show ("implementation of Show interface" in OOP parlance), so you can at least print the contents of the list.
Note that earlier we could not include arr in itself only because there was nothing common between a and [a]. But the latter example is a valid construct once you can determine what's the common operation that all the elements in the list support. If you can define such a function for [T], then you can include arr in the list of itself - this function determines what's common between certain kinds of a and [a].
No. We could emulate:
data ValueRef a = Ref | Value a deriving Show
lref :: [ValueRef Int]
lref = [Value 2, Ref, Value 1]
getValue :: [ValueRef a] -> Int -> [ValueRef a]
getValue lref index = case lref !! index of
Ref -> lref
a -> [a]
and have results:
>getValue lref 0
[Value 2]
>getValue lref 1
[Value 2,Ref,Value 1]
Sure, we could reuse Maybe a instead of ValueRef a

Haskell: list of elements with class restriction

here's my question:
this works perfectly:
type Asdf = [Integer]
type ListOfAsdf = [Asdf]
Now I want to do the same but with the Integral class restriction:
type Asdf2 a = (Integral a) => [a]
type ListOfAsdf2 = (Integral a) => [Asdf2 a]
I got this error:
Illegal polymorphic or qualified type: Asdf2 a
Perhaps you intended to use -XImpredicativeTypes
In the type synonym declaration for `ListOfAsdf2'
I have tried a lot of things but I am still not able to create a type with a class restriction as described above.
Thanks in advance!!! =)
Dak
Ranting Against the Anti-Existentionallists
I always dislike the anti-existential type talk in Haskell as I often find existentials useful. For example, in some quick check tests I have code similar to (ironically untested code follows):
data TestOp = forall a. Testable a => T String a
tests :: [TestOp]
tests = [T "propOne:" someProp1
,T "propTwo:" someProp2
]
runTests = mapM runTest tests
runTest (T s a) = putStr s >> quickCheck a
And even in a corner of some production code I found it handy to make a list of types I'd need random values of:
type R a = Gen -> (a,Gen)
data RGen = forall a. (Serialize a, Random a) => RGen (R a)
list = [(b1, str1, random :: RGen (random :: R Type1))
,(b2, str2, random :: RGen (random :: R Type2))
]
Answering Your Question
{-# LANGUAGE ExistentialQuantification #-}
data SomeWrapper = forall a. Integral a => SW a
If you need a context, the easiest way would be to use a data declaration:
data (Integral a) => IntegralData a = ID [a]
type ListOfIntegralData a = [IntegralData a]
*Main> :t [ ID [1234,1234]]
[ID [1234,1234]] :: Integral a => [IntegralData a]
This has the (sole) effect of making sure an Integral context is added to every function that uses the IntegralData data type.
sumID :: Integral a => IntegralData a -> a
sumID (ID xs) = sum xs
The main reason a type synonym isn't working for you is that type synonyms are designed as
just that - something that replaces a type, not a type signature.
But if you want to go existential the best way is with a GADT, because it handles all the quantification issues for you:
{-# LANGUAGE GADTs #-}
data IntegralGADT where
IG :: Integral a => [a] -> IntegralGADT
type ListOfIG = [ IntegralGADT ]
Because this is essentially an existential type, you can mix them up:
*Main> :t [IG [1,1,1::Int], IG [234,234::Integer]]
[IG [1,1,1::Int],IG [234,234::Integer]] :: [ IntegralGADT ]
Which you might find quite handy, depending on your application.
The main advantage of a GADT over a data declaration is that when you pattern match, you implicitly get the Integral context:
showPointZero :: IntegralGADT -> String
showPointZero (IG xs) = show $ (map fromIntegral xs :: [Double])
*Main> showPointZero (IG [1,2,3])
"[1.0,2.0,3.0]"
But existential quantification is sometimes used for the wrong reasons,
(eg wanting to mix all your data up in one list because that's what you're
used to from dynamically typed languages, and you haven't got used to
static typing and its advantages yet).
Here I think it's more trouble than it's worth, unless you need to mix different
Integral types together without converting them. I can't see a reason
why this would help, because you'll have to convert them when you use them.
For example, you can't define
unIG (IG xs) = xs
because it doesn't even type check. Rule of thumb: you can't do stuff that mentions the type a on the right hand side.
However, this is OK because we convert the type a:
unIG :: Num b => IntegralGADT -> [b]
unIG (IG xs) = map fromIntegral xs
Here existential quantification has forced you convert your data when I think your original plan was to not have to!
You may as well convert everything to Integer instead of this.
If you want things simple, keep them simple. The data declaration is the simplest way of ensuring you don't put data in your data type unless it's already a member of some type class.

Resources