haskell class property check - class

I would like to have a function that checks a property of a class instance:
class ListWithAtLeastOneElement a where
list :: [a]
check :: Bool
check = (length list) >= 1
but I get this error when compiling in GHC:
"The class method 'check' mentions none of the type variables of the class ListWithAtLeastOneElement a When checking the class method: check :: Bool In the class declaration for 'ListWithAtLeastOneElement'"
Is there a better way of doing what I want, or a way to get this to compile in GHC?

You seem to think a class in Haskell is like a class in an OO-language. That is not true. You should use a data type or newtype or type synonym.
newtype NonemptyList a = List1 [a]
fromList :: [a] -> Maybe (NonemptyList a)
fromList [] = Nothing
fromList xs#(_:_) = Just $ List1 xs
check :: NonemptyList a -> Bool
check (List1 xs) = length xs >= 1

As jmg said, this isn't valid Haskell so it's good GHC isn't compiling it! If you're used to Java evidently you should think of Haskell's type classes like Java interface. If that doesn't help then perhaps you should read LYAH's chapter on classes.
For you problem, it appears you're wanting a list-like data type that can never be null. You don't need to test for such a property, you can statically ensure it by using a data
type that can never be empty:
-- Notice this data type can never have zero 'a' values!
data NonEmptyList a = NEL a (NonEmptyList a) | Singleton a
-- We can define basic operators for this, just like list has
-- You can't pattern match with them, but there are work-arounds for that if you want to ask
(.:) = NEL -- concatenate non-empty lists
nelHead :: NonEmptyList a -> a
nelHead (NEL a _) = a
nelHead (Singleton a) = a
nelTail :: NonEmptyList a -> Maybe (NonEmptyList a)
nelTail (NEL _ b) = Just b
nelTail _ = Nothing
nelTake :: Int -> NonEmptyList a -> NonEmptyList a
nelTake 1 (NEL a _) = Singleton a
nelTake 1 (Singleton a) = Singleton a
nelTake n (NEL a rest) = a .: nelTake (n-1) rest
nelDrop :: Int -> NonEmptyList a -> NonEmptyList a
nelDrop _ (Singleton _) = error "Perhaps I should have used the 'maybe' type"
nelDrop 1 (NEL a r) = r
nelDrop n (NEL a r) = nelDrop (n-1) r
And so on and so forth. It's worth noting nelTake and nelDrop are partial but nelHead is total, funny as this is the opposite of regular lists.

You would need to make check a function
check :: [a] -> Bool
That said you are better off with a data type for non-empty lists rather than a class, classes in Haskell do not serve the same purpose as classes in object oriented languages.

Related

Writing Functor instance vs. writing Eq instance for NonEmpty in Purescript

I'm currently learning Purescript by reading the Purescript by Example book (so far one of the only resources I've found that covers the language extensively).
I'm trying to implement the exercises in section 6.7 (Instance Dependencies), and I can't get my head around the following compiler error:
I've implemented the Semigroup and Eq instances for a data type data NonEmpty a = NonEmpty a (Array a) as follows:
instance eqNonEmpty :: Eq a => Eq (NonEmpty a) where
eq (NonEmpty h1 t1) (NonEmpty h2 t2) = h1 == h2 && t1 == t2
instance semigroupNonEmpty :: Semigroup (NonEmpty a) where
append (NonEmpty h1 t1) (NonEmpty h2 t2) = NonEmpty h1 (t1 <> [h2] <> t2)
But when I try to implement the Functor instance the same way I get the error above.
What seems to work is this:
instance functorNonEmpty :: Functor NonEmpty where
map f (NonEmpty h t) = NonEmpty (f h) (map f t)
Now, why is that? I can't figure it out.
Thanks!
That's just how the Functor class is defined: it applies to types that take a parameter. So, for example, the Functor class would apply to Maybe and to List, but wouldn't apply to Int or to String, and equally wouldn't apply to Maybe Int or List String.
The type NonEmpty does take a parameter, because that's how it is defined:
data NonEmpty a = ...
But a type NonEmpty a does not take a parameter, regardless of what a might be.
The classes Eq and Semigroup, on the other hand, expect a type without any parameters. So these classes can apply to Int, String, Maybe Boolean, and any other type without parameters, including NonEmpty a, regardless of what a might be.

Similar record types in a list/array in purescript

Is there any way to do something like
first = {x:0}
second = {x:1,y:1}
both = [first, second]
such that both is inferred as {x::Int | r} or something like that?
I've tried a few things:
[{x:3}] :: Array(forall r. {x::Int|r}) -- nope
test = Nil :: List(forall r. {x::Int|r})
{x:1} : test -- nope
type X r = {x::Int | r}
test = Nil :: List(X) -- nope
test = Nil :: List(X())
{x:1} : test
{x:1, y:1} : test -- nope
Everything I can think of seems to tell me that combining records like this into a collection is not supported. Kind of like, a function can be polymorphic but a list cannot. Is that the correct interpretation? It reminds me a bit of the F# "value restriction" problem, though I thought that was just because of CLR restrictions whereas JS should not have that issue. But maybe it's unrelated.
Is there any way to declare the list/array to support this?
What you're looking for is "existential types", and PureScript just doesn't support those at the syntax level the way Haskell does. But you can roll your own :-)
One way to go is "data abstraction" - i.e. encode the data in terms of operations you'll want to perform on it. For example, let's say you'll want to get the value of x out of them at some point. In that case, make an array of these:
type RecordRep = Unit -> Int
toRecordRep :: forall r. { x :: Int | r } -> RecordRep
toRecordRep {x} _ = x
-- Construct the array using `toRecordRep`
test :: Array RecordRep
test = [ toRecordRep {x:1}, toRecordRep {x:1, y:1} ]
-- Later use the operation
allTheXs :: Array Int
allTheXs = test <#> \r -> r unit
If you have multiple such operations, you can always make a record of them:
type RecordRep =
{ getX :: Unit -> Int
, show :: Unit -> String
, toJavaScript :: Unit -> Foreign.Object
}
toRecordRep r =
{ getX: const r.x
, show: const $ show r.x
, toJavaScript: const $ unsafeCoerce r
}
(note the Unit arguments in every function - they're there for the laziness, assuming each operation could be expensive)
But if you really need the type machinery, you can do what I call "poor man's existential type". If you look closely, existential types are nothing more than "deferred" type checks - deferred to the point where you'll need to see the type. And what's a mechanism to defer something in an ML language? That's right - a function! :-)
newtype RecordRep = RecordRep (forall a. (forall r. {x::Int|r} -> a) -> a)
toRecordRep :: forall r. {x::Int|r} -> RecordRep
toRecordRep r = RecordRep \f -> f r
test :: Array RecordRep
test = [toRecordRep {x:1}, toRecordRep {x:1, y:1}]
allTheXs = test <#> \(RecordRep r) -> r _.x
The way this works is that RecordRep wraps a function, which takes another function, which is polymorphic in r - that is, if you're looking at a RecordRep, you must be prepared to give it a function that can work with any r. toRecordRep wraps the record in such a way that its precise type is not visible on the outside, but it will be used to instantiate the generic function, which you will eventually provide. In my example such function is _.x.
Note, however, that herein lies the problem: the row r is literally not known when you get to work with an element of the array, so you can't do anything with it. Like, at all. All you can do is get the x field, because its existence is hardcoded in the signatures, but besides the x - you just don't know. And that's by design: if you want to put anything into the array, you must be prepared to get anything out of it.
Now, if you do want to do something with the values after all, you'll have to explain that by constraining r, for example:
newtype RecordRep = RecordRep (forall a. (forall r. Show {x::Int|r} => {x::Int|r} -> a) -> a)
toRecordRep :: forall r. Show {x::Int|r} => {x::Int|r} -> RecordRep
toRecordRep r = RecordRep \f -> f r
test :: Array RecordRep
test = [toRecordRep {x:1}, toRecordRep {x:1, y:1}]
showAll = test <#> \(RecordRep r) -> r show
Passing the show function like this works, because we have constrained the row r in such a way that Show {x::Int|r} must exist, and therefore, applying show to {x::Int|r} must work. Repeat for your own type classes as needed.
And here's the interesting part: since type classes are implemented as dictionaries of functions, the two options described above are actually equivalent - in both cases you end up passing around a dictionary of functions, only in the first case it's explicit, but in the second case the compiler does it for you.
Incidentally, this is how Haskell language support for this works as well.
Folloing #FyodorSoikin answer based on "existential types" and what we can find in purescript-exists we can provide yet another solution.
Finally we will be able to build an Array of records which will be "isomorphic" to:
exists tail. Array { x :: Int | tail }
Let's start with type constructor which can be used to existentially quantify over a row type (type of kind #Type). We are not able to use Exists from purescript-exists here because PureScript has no kind polymorphism and original Exists is parameterized over Type.
newtype Exists f = Exists (forall a. f (a :: #Type))
We can follow and reimplement (<Ctrl-c><Ctrl-v> ;-)) definitions from Data.Exists and build a set of tools to work with such Exists values:
module Main where
import Prelude
import Unsafe.Coerce (unsafeCoerce)
import Data.Newtype (class Newtype, unwrap)
newtype Exists f = Exists (forall a. f (a :: #Type))
mkExists :: forall f a. f a -> Exists f
mkExists r = Exists (unsafeCoerce r :: forall a. f a)
runExists :: forall b f. (forall a. f a -> b) -> Exists f -> b
runExists g (Exists f) = g f
Using them we get the ability to build an Array of Records with "any" tail but we have to wrap any such a record type in a newtype before:
newtype R t = R { x :: Int | t }
derive instance newtypeRec :: Newtype (R t) _
Now we can build an Array using mkExists:
arr :: Array (Exists R)
arr = [ mkExists (R { x: 8, y : "test"}), mkExists (R { x: 9, z: 10}) ]
and process values using runExists:
x :: Array [ Int ]
x = map (runExists (unwrap >>> _.x)) arr

Scala's Partial Functions in Haskell

Scala has a very nice support of partial functions, mainly because in Scala when you define a partial function it also defines an isDefinedAt function for it. And also Scala has orElse and andThen functions to work with partial functions.
Haskell does support partial functions by simply non-exhaustively defining a function (though they are strongly discouraged in Haskell community). But to define isDefinedAt function in general you have to use some sort of exception handling, which I'm not being able to figure out. Once isDefinedAt function is defined then it can be used to define orElse and andThen function is already there as (.).
In short, I want to define a function,
isDefinedAt :: (a -> b) -> a -> Bool
isDefinedAt f x = -- returns True if f is defined at x else False
Can anyone please tell me how such a function can be written.
Note, I can define a function with signature
isDefinedAt :: (a -> b) -> a -> IO Bool
for generic b. But I want a function without IO in co-domain.
A nice article on Scala's Partial Functions is - How to create and use partial functions in Scala By Alvin Alexander
I recommend that, like in Scala, you use a separate type for partial functions.
import Control.Arrow
import Data.Maybe
type Partial = Kleisli Maybe
isDefinedAt :: Partial a b -> a -> Bool
isDefinedAt f x = isJust $ runKleisli f x
-- laziness should save some of the work, if possible
orElse :: Partial a b -> Partial a b -> Partial a b
orElse = (<+>)
andThen :: Partial a b -> Partial b c -> Partial a c
andThen = (>>>)
Your versions of isDefinedAt are not what Scala does (even in signature); it's very possible (though discouraged) for a PartialFunction to throw an exception when isDefinedAt is true. Or, when you define one explicitly (not using a literal), vice versa: apply doesn't have to throw when isDefinedAt is false, it's user responsibility not to call it then. So the direct equivalent would just be
data PartialFunction a b = PartialFunction { apply :: a -> b, isDefinedAt :: a -> Boolean }
which isn't particularly useful.
apply and isDefinedAt are only really linked in Scala for PartialFunction literals which requires compiler support:
A PartialFunction's value receives an additional isDefinedAt member, which is derived from the pattern match in the function literal, with each case's body being replaced by true, and an added default (if none was given) that evaluates to false.
You can emulate this by using Template Haskell, I believe, but I honestly think using the more Haskell-like approach as described in Daniel Wagner's answer is better. As he mentions, laziness helps.
Though it works even better if you make sure runKleisli f x is executed only once; optimizing cases where you have both isDefinedAt and runKleisli requires Common Subexpression Elimination, and the compiler is cautious about doing that, see Under what circumstances could Common Subexpression Elimination affect the laziness of a Haskell program?
You could do something like this (DISCLAIMER: I have not checked the laws of the relevant typeclasses, and the presence of a string in the constructor for the exception in Alternative makes me wonder if it is lawful). Scala's heterogeneous andThen is covered by fmap; its homogeneous andThen / compose are covered by the >>> / <<< from Category; orElse is covered by <|>; lift is runToMaybe.
However, without a deep compiler integration such as exists in Scala, the pattern incompleteness warnings will interact poorly with this. Haskell only has module-level pragmas for these things, and you won't want to just indiscriminately turn them off in any module where you declare inexhaustive functions, or you may get nasty surprises. Depending on your usecase, you may find optics more idiomatic and less problematic; you can have the boilerplate generated for you through Template Haskell.
(Note: I called it Inexhaustive because PartialFunction is something of a misnomer, in that it implies that Function is total. But Scala has no termination or positivity checkers, so the compiler is not actually able to talk about totality; so you get this weird situation where a function that is not a partial function is just a "regular" Function, whereas you should be able to call it a "total Function". The question here is not partially or totality, which is a broader idea, but inexhaustivity of pattern matches.)
{-# LANGUAGE TypeApplications #-}
module Inexhaustive
( Inexhaustive, inexhaustive
, runToMaybe, isDefinedAt
) where
import Prelude hiding ((.), id)
import Control.Applicative
import Control.Exception
import Control.Category
import Data.Maybe
import System.IO.Unsafe (unsafePerformIO)
newtype Inexhaustive a b = Inexhaustive (a -> b)
inexhaustive :: (a -> b) -> Inexhaustive a b
inexhaustive = Inexhaustive
runToMaybe :: Inexhaustive a b -> a -> Maybe b
runToMaybe (Inexhaustive f) x =
let io = fmap Just $ evaluate $ f x
in unsafePerformIO $ catch #PatternMatchFail io (\_ -> return Nothing)
isDefinedAt :: Inexhaustive a b -> a -> Bool
isDefinedAt f = isJust . runToMaybe f
instance Functor (Inexhaustive z) where
fmap f (Inexhaustive g) = inexhaustive (f . g)
instance Applicative (Inexhaustive z) where
pure x = inexhaustive (const x)
(Inexhaustive zab) <*> (Inexhaustive za) = Inexhaustive (\z -> zab z $ za z)
instance Alternative (Inexhaustive z) where
empty = inexhaustive (\_ -> throw $ PatternMatchFail "inexhaustive empty")
f <|> g =
inexhaustive $ \x ->
case runToMaybe f x <|> runToMaybe g x of
Just y -> y
instance Category Inexhaustive where
id = inexhaustive id
(Inexhaustive f) . (Inexhaustive g) = Inexhaustive (f . g)

Higher kinded Types and Type arguments for classes

Suppose you are using the FlexibleInstances extension and have the class
class C a where
f :: a b -> Maybe b
how would you implement it for a list of lists of a datatype. In particular, how would the type be written. The only thing I could find is how to do it for a single list, but not a list of lists or lists of any other datatypes.
This works:
instance C [] where
...
But this doesn't
data D = ...
instance C [[D]] where
...
How can I express something like this?
You need a newtype
class C a where
f :: a b -> b -- the class before the OP edited
newtype LL a = LL [[a]]
instance C LL where
f (LL xss) = ...
However, it is impossible to write a completely meaningful instance, since if the lists-of-lists is empty, it is impossible to extract an element. the best we could do is
instance C LL where
f (LL xss) = case concat xss of
(x:_) -> x
_ -> error "f: no elements"
I'm not sure if that is a good idea.
As an alternative, you could use type families or functional dependencies. Here's a solution with type families.
{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
class C a where
type T a
f :: a -> Maybe (T a)
instance C [[b]] where
type T [[b]] = b
f xss = case concat xss of
[] -> Nothing
(x:_) -> Just x

Gentle Intro to Haskell: " .... there is no single type that contains both 2 and 'b'." Can I not make such a type ?

I am currently learning Haskell, so here are a beginner's questions:
What is meant by single type in the text below ?
Is single type a special Haskell term ? Does it mean atomic type here ?
Or does it mean that I can never make a list in Haskell in which I can put both 1 and 'c' ?
I was thinking that a type is a set of values.
So I cannot define a type that contains Chars and Ints ?
What about algebraic data types ?
Something like: data IntOrChar = In Int | Ch Char ? (I guess that should work but I am confused what the author meant by that sentence.)
Btw, is that the only way to make a list in Haskell in which I can put both Ints and Chars? Or is there a more tricky way ?
A Scala analogy: in Scala it would be possible to write implicit conversions to a type that represents both Ints and Chars (like IntOrChar) and then it would be possible to put seemlessly Ints and Chars into List[IntOrChar], is that not possible with Haskell ? Do I always have to explicitly wrap every Int or Char into IntOrChar if I want to put them into a list of IntOrChar ?
From Gentle Intro to Haskell:
Haskell also incorporates polymorphic types---types that are
universally quantified in some way over all types. Polymorphic type
expressions essentially describe families of types. For example,
(forall a)[a] is the family of types consisting of, for every type a,
the type of lists of a. Lists of integers (e.g. [1,2,3]), lists of
characters (['a','b','c']), even lists of lists of integers, etc., are
all members of this family. (Note, however, that [2,'b'] is not a
valid example, since there is no single type that contains both 2 and
'b'.)
Short answer.
In Haskell there are no implicit conversions. Also there are no union types - only disjoint unions(which are algebraic data types). So you can only write:
someList :: [IntOrChar]
someList = [In 1, Ch 'c']
Longer and certainly not gentle answer.
Note: This is a technique that's very rarely used. If you need it you're probably overcomplicating your API.
There are however existential types.
{-# LANGUAGE ExistentialQuantification, RankNTypes #-}
class IntOrChar a where
intOrChar :: a -> Either Int Char
instance IntOrChar Int where
intOrChar = Left
instance IntOrChar Char where
intOrChar = Right
data List = Nil
| forall a. (IntOrChar a) => Cons a List
someList :: List
someList = (1 :: Int) `Cons` ('c' `Cons` Nil)
Here I have created a typeclass IntOrChar with only function intOrChar. This way you can convert anything of type forall a. (IntOrChar a) => a to Either Int Char.
And also a special kind of list that uses existential type in its second constructor.
Here type variable a is bound(with forall) at the constructor scope. Therefore every time
you use Cons you can pass anything of type forall a. (IntOrChar a) => a as a first argument. Consequently during a destruction(i.e. pattern matching) the first argument will
still be forall a. (IntOrChar a) => a. The only thing you can do with it is either pass it on or call intOrChar on it and convert it to Either Int Char.
withHead :: (forall a. (IntOrChar a) => a -> b) -> List -> Maybe b
withHead f Nil = Nothing
withHead f (Cons x _) = Just (f x)
intOrCharToString :: (IntOrChar a) => a -> String
intOrCharToString x =
case intOrChar of
Left i -> show i
Right c -> show c
someListHeadString :: Maybe String
someListHeadString = withHead intOrCharToString someList
Again note that you cannot write
{- Wont compile
safeHead :: IntOrChar a => List -> Maybe a
safeHead Nil = Nothing
safeHead (Cons x _) = Just x
-}
-- This will
safeHead2 :: List -> Maybe (Either Int Char)
safeHead2 Nil = Nothing
safeHead2 (Cons x _) = Just (intOrChar x)
safeHead will not work because you want a type of IntOrChar a => Maybe a with a bound at safeHead scope and Just x will have a type of IntOrChar a1 => Maybe a1 with a1 bound at Cons scope.
In Scala there are types that include both Int and Char such as AnyVal and Any, which are both supertypes of Char and Int. In Haskell there is no such hierarchy, and all the basic types are disjoint.
You can create your own union types which describe the concept of 'either an Int or a Char (or you could use the built-in Either type), but there are no implicit conversions in Haskell to transparently convert an Int into an IntOrChar.
You could emulate the concept of 'Any' using existential types:
data AnyBox = forall a. (Show a, Hashable a) => AB a
heteroList :: [AnyBox]
heteroList = [AB (1::Int), AB 'b']
showWithHash :: AnyBox -> String
showWithHash (AB v) = show v ++ " - " ++ (show . hash) v
let strs = map showWithHash heteroList
Be aware that this pattern is discouraged however.
I think that the distinction that is being made here is that your algebraic data type IntOrChar is a "tagged union" - that is, when you have a value of type IntOrChar you will know if it is an Int or a Char.
By comparison consider this anonymous union definition (in C):
typedef union { char c; int i; } intorchar;
If you are given a value of type intorchar you don't know (apriori) which selector is valid. That's why most of the time the union constructor is used in conjunction with a struct to form a tagged-union construction:
typedef struct {
int tag;
union { char c; int i; } intorchar_u
} IntOrChar;
Here the tag field encodes which selector of the union is valid.
The other major use of the union constructor is to overlay two structures to get an efficient mapping between sub-structures. For example, this union is one way to efficiently access the individual bytes of a int (assuming 8-bit chars and 32-bit ints):
union { char b[4]; int i }
Now, to illustrate the main difference between "tagged unions" and "anonymous unions" consider how you go about defining a function on these types.
To define a function on an IntOrChar value (the tagged union) I claim you need to supply two functions - one which takes an Int (in the case that the value is an Int) and one which takes a Char (in case the value is a Char). Since the value is tagged with its type, it knows which of the two functions it should use.
If we let F(a,b) denote the set of functions from type a to type b, we have:
F(IntOrChar,b) = F(Int,b) \times F(Char,b)
where \times denotes the cross product.
As for the anonymous union intorchar, since a value doesn't encode anything bout its type the only functions which can be applied are those which are valid for both Int and Char values, i.e.:
F(intorchar,b) = F(Int,b) \cap F(Char,b)
where \cap denotes intersection.
In Haskell there is only one function (to my knowledge) which can be applied to both integers and chars, namely the identity function. So there's not much you could do with a list like [2, 'b'] in Haskell. In other languages this intersection may not be empty, and then constructions like this make more sense.
To summarize, you can have integers and characters in the same list if you create a tagged-union, and in that case you have to tag each of the values which will make you list look like:
[ I 2, C 'b', ... ]
If you don't tag your values then you are creating something akin to an anonymous union, but since there aren't any (useful) functions which can be applied to both integers and chars there's not really anything you can do with that kind of union.