A Simple Haskell Operator [closed] - haskell

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
For my assignment, we have to write a primitive function which looks like this:
My question is Prim Eq, Prim Less, Prim Great should be able to take any kinds of parameters such as String, Number although its return type is always boolean... So I am not sure how to specify the types a and b.
If you know how to approach this, please let me know. I'd really appreciate your help.
Thank you very much.

prim Less [Number a, Number b] = Bool (a < b)
prim Less [String a, String b] = Bool (a < b)
prim Great [Number a, Number b] = Bool (a > b)
prim Great [String a, String b] = Bool (a > b)
a and b are not types; they're values. I'm not sure what you want to specify here.

What you want to look at is GADTs. However you maybe won't be able to have your prim function, but you can get more type safety if you could add type signatures to constructors, like Eq :: Value a -> Value a -> Value Bool and the way to do this is GADTs.

Related

The difference between (a -> Bool) and (a -> a -> Bool) in Haskell? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am currently learning Haskell and came across a type signature that confused me.
I know that:
(a -> Bool)
Is how a predicate is assigned in the type signature when using (Ord a) but I came across a type signature that is declared as:
(a -> a -> Bool)
Which according to what I found online is a type signature for inequalities but I am confused as to if they are for adding an inequality to a predicate, ie:
(> p x == True)
Or if they are just to declare inequalities by themselves.
Thanks.
When some function has a typesignature (a -> Bool) it just means it takes a value of some unconstrained type a and returns a Bool, i.e. True or False. You can however restrict the type variable a and get something like this Ord a => a -> Bool, it restricts the polymorphic type a in that sense that a has to have an instance of type class Ord.
You can also partially apply functions. e.g (>) :: Ord a => a -> a -> Bool and when you partially apply > with 5 you get (>5) :: (Ord a, Num a) => a -> Bool. That is a new function that takes something that has to have the type class Ord as well as the type class Num, and returns True or False.
To answer your question, you can of course create a new function by applying a constant to another function. You also don't really need the == if all you want to do is, check if a number is strictly bigger than a constant.
f = (>) 5
f 4 -- True
f 5 -- False
I hope this helps you to get started with haskell. You should probably read some tutorial to get a good overview though. I can recommend learn you a haskell.

Why aren't there existentially quantified type variables in GHC Haskell

There are universally quantified type variables, and there are existentially quantified data types. However, despite that people give pseudocode of the form exists a. Int -> a to help explain concepts sometimes, it doesn't seem like a compiler extension that there's any real interest in. Is this just a "there isn't much value in adding this" kind of thing (because it does seem valuable to me), or is there a problem like undecidability that's makes it truly impossible.
EDIT:
I've marked viorior's answer as correct because it seems like it is probably the actual reason why this was not included. I'd like to add some additional commentary though just in case anyone would want to help clarify this more.
As requested in the comments, I'll give an example of why I would consider this useful. Suppose we have a data type as follows:
data Person a = Person
{ age: Int
, height: Double
, weight: Int
, name: a
}
So we choose parameterize over a, which is a naming convention (I know that it probably makes more sense in this example to make a NamingConvention ADT with appropriate data constructors for the American "first,middle,last", the hispanic "name,paternal name,maternal name", etc. But for now, just go with this).
So, there are several functions we see that basically ignore the type that Person is parameterized over. Examples would be
age :: Person a -> Int
height :: Person a -> Double
weight :: Person a -> Int
And any function built on top of these could similarly ignore the a type. For example:
atRiskForDiabetes :: Person a -> Bool
atRiskForDiabetes p = age p + weight p > 200
--Clearly, I am not actually a doctor
Now, if we have a heterogeneous list of people (of type [exists a. Person a]), we would like to be able to map some of our functions over the list. Of course, there are some useless ways to map:
heteroList :: [exists a. Person a]
heteroList = [Person 20 30.0 170 "Bob Jones", Person 50 32.0 140 3451115332]
extractedNames = map name heteroList
In this example, extractedNames is of course useless because it has type [exists a. a]. However, if we use our other functions:
totalWeight :: [exists a. Person a] -> Int
totalWeight = sum . map age
numberAtRisk :: [exists a. Person a] -> Int
numberAtRisk = length . filter id . map atRiskForDiabetes
Now, we have something useful that operates over a heterogeneous collection (And, we didn't even involve typeclasses). Notice that we were able to reuse our existing functions. Using an existential data type would go as follows:
data SomePerson = forall a. SomePerson (Person a) --fixed, thanks viorior
But now, how can we use age and atRiskForDiabetes? We can't. I think that you would have to do something like this:
someAge :: SomePerson -> Int
someAge (SomePerson p) = age p
Which is really lame because you have to rewrite all of your combinators for a new type. It gets even worse if you want to do this with a data type that's parameterized over several type variables. Imagine this:
somewhatHeteroPipeList :: forall a b. [exists c d. Pipe a b c d]
I won't explain this line of thought any further, but just notice that you'd be rewriting a lot of combinators to do anything like this using just existential data types.
That being said, I hope I've give a mildly convincing use that this could be useful. If it doesn't seem useful (or if the example seems too contrived), feel free to let me know. Also, since I am firstly a programmer and have no training in type theory, it's a little difficult for me to see how to use Skolem's theorum (as posted by viorior) here. If anyone could show me how to apply it to the Person a example I gave, I would be very grateful. Thanks.
It is unnecessary.
By Skolem's Theorem we could convert existential quantifier into universal quantifier with higher rank types:
(∃b. F(b)) -> Int <===> ∀b. (F(b) -> Int)
Every existentially quantified type of rank n+1 can be encoded as a universally quantified type of rank n
Existentially quantified types are available in GHC, so the question is predicated on a false assumption.

Haskell, creating a structured datatype [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I would like to create a structure datatype called Structured that can be used to represent String, Int and List. For example, structure is like: [Int, String, Int,[Int]].
Question 1: how to create this datatype?
data Structured = ...
Question 2: A function called Confirm that confirms the input satisfies a restriction, and has the signature type of confirm:: Restriction -> Structure ->Maybe Bool
data Structured = Structured Int String Int [Int]
would work.
confirm :: (Structured -> Bool) -> Structured -> Bool
seems a more sensible type, but has a trivial implementation as id.
I don't think you would need to return Maybe Bool from a valudation function - Maybe a is good for when you usually resturn an a, but sometimes don't. (It's good for very simple error handling, for example - give Nothing if there was an error.) In this case, you can always make a conclusion as to whether your input was valid, so you can always give back True or False - no need for the Maybe.
Perhaps you could have something like
confirm :: (String -> Bool) -> (Int -> Bool) -> Structured -> Bool
confirm okString okInt (Structured int1 string int2 ints) =
all okInt (int1:int2:ints) && okString string
Here int1:int2:ints is the list that has int1 in front of int2 in front of ints.
A slightly nicer way of defining Structured would be:
data Structured = Structured {
length ::Int,
name ::String,
width ::Int,
somenumbers :: [Int]}
then you'd have
confirm :: (String -> Bool) -> (Int -> Bool) -> Structured -> Bool
confirm okString okInt s =
all okInt (length s:width s:somenumbers s) && okString (name s)
It does the same job as the first data declaration, but gives you functions for getting at the internals.

Haskell, how to convert ADT to String? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
here is my ADT:
data Tree a = Val Integer
|Tree a
|Variable a
I have two questions:
Question 1: use Tree String type to represent some trees?
Question 2: define a function for converting a tree, an element of the datatype Tree String to string: showTree::Tree String -> String
With respect to your second question, coverting a tree into a string, just derive Show and use the show function:
data Tree a = Val Integer
| Tree a
| Variable a
deriving (Eq, Ord, Show)
showTree :: (Show a) => Tree a -> String
showTree = show
I don't understand your first question, so I'm just going to talk a bit in hopes that something I say helps you.
Understand that your "tree" data type is not really a tree at all, it's just a sum data type that can be instantiated by an integer or some type that matches the type variable, a. The second constructor, Tree, is actually not making your data type recursive - its just a constructor name in the same way Variable is a constructor name. I think you probably wanted to have subtrees (by using Tree as a type, not a constructor) - so let's define your type as:
data Tree a = Val Integer
| Branch (Tree a) (Tree a)
| Variable a
Now you have a constructor named Branch that has a left and a right sub-tree. If your variables are supposed to be Strings then you certainly can use Tree String to represent this:
myTree :: Tree String
myTree =
let leftBranch = Variable "x"
rightBranch = Branch (Val 3) (Variable "y")
in Branch leftBranch rightBranch

overloading in different programming languages [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Can somebody please explain (with example) the difference between context-independent and context-dependent overloading?
I have never heard about those. And there's only about five hits on Google, one of which is this very question, which seems to suggest to me that these are made-up terms. And as with any made-up term, if you want to know what it means, you have to ask the person who made it up.
From what little I could gather, it seems to be related to return-type based overloading.
Basically, if you have four overloaded functions like these:
foo :: string → int
foo :: string → string
foo :: string → ()
foo :: int → int
And you call them like this:
1 + foo 1
1 + foo "one"
foo "one"
Then, with context-dependent overloading (i.e. overloading based on the return type as well as the parameter types), the following implementations will be selected:
1 + foo 1 # foo :: int → int
1 + foo "one" # foo :: string → int (because `+` takes an `int`)
foo "one" # foo :: string → () (because there is no return value)
Whereas with context-independent overloading (i.e. ignoring the return type), the following implementations will be selected:
1 + foo 1 # foo :: int → int
1 + foo "one" # ERROR
foo "one" # ERROR
In both the ERROR cases, there is an ambiguity between foo :: string → int, foo :: string → string and foo :: string → (), since they only differ in their return type but have the same paremeter type.
Quoting from here:
There are two kinds of overloading of
functions/operators.
context-independent - overloading only done on parameters to
function or type of operands for an
operator
context-dependent - which abstraction to call also depends upon
the type of the result

Resources