In my homework, we are given a regular expression. I have to return an e-NFA. I'm trying to build the delta function. So far I have:
module ConsENFA where
import Data.Set (Set, fromList, singleton, empty)
import RegEx
import ENFA
epsilon :: RegExp Char
epsilon = Symbol 'e'
deltaTest :: RegExp Char -> Int -> (Int -> Char -> Set Int)
deltaTest (Symbol sym) start = delta
where
delta :: Int -> Char -> Set Int
delta start sym = singleton (start + 1)
deltaTest (Star re) start = delta
where
delta :: Int -> Char -> Set Int
delta = deltaTest re (start + 1)
delta start epsilon = fromList[1, 3]
I got the error
ConsENFA.hs:19:9: error:
Conflicting definitions for `delta'
Bound at: ConsENFA.hs:19:9-13
ConsENFA.hs:20:9-13
which I assume means that I can't expand the pattern matching like that, I can't add more states.
I first define delta for a single label and then I add more definitions to the previously defined delta, but it's not working. What's the correct way to do it?
All definitions of a function must have the same arity, i.e., the same number of function arguments. You define delta in three lines:
The first line is a type signature.
The second line is a definition of delta with arity zero (no arguments to the left of the =)
The third line is another definition of delta with arity two (two arguments to the left of the =)
The two definitions have a different arity, so the compiler tells you there are conflicting definitions.
Ask yourself: What is the inteded behavior of delta? The compiler will look at the definitions of delta in the order they are defined, and choose the first one where a pattern match succeeds. Since there are no arguments in the first definition (and hence no patterns to match), it will always succeed and the second definition will never be called.
Related
I am working on the Haskell project,
For the error checking, I need to take care of any function call having too many or too few arguments, but I currently have no idea for it.Hoping to get same hints to start.
Unless one uses some form of advanced ad hoc polymorphism like the printf :: PrintfType r => String -> r does, the compiler will notice.
Indeed, if you have a function like:
add :: Int -> Int -> Int
add = (+)
if you call it with three parameters, like add 2 4 5, then this will raise an error. This will happen, since add 2 4 5, or more canonical ((add 2) 4) 5, will try to eventually make a call to an item that is an Int. Indeed add 2 has type add 2 :: Int -> Int, and thus (add 2) 4 has type (add 2) 4 :: Int, so since that is not function, the compiler will raise an error:
Prelude> add 2 4 5
<interactive>:5:1: error:
• Couldn't match expected type ‘Integer -> t’
with actual type ‘Int’
• The function ‘add’ is applied to three arguments,
but its type ‘Int -> Int -> Int’ has only two
In the expression: add 2 4 5
In an equation for ‘it’: it = add 2 4 5
• Relevant bindings include it :: t (bound at <interactive>:5:1)
It thus says it expected a type (Integer -> t, although the Integer here is due to type defaulting), but got an Int instead. So that is not possible.
Calling a function with "too few" parameters is not really possible, since if you call it with too few, you simply generate a function that expects to take the next parameter. This is the idea behind currying [Haskell-wiki]. Indeed, if the type of add 2 is:
Prelude> :t add 2
add 2 :: Int -> Int
It is a function that expects the following parameter. It is possible that this will clash with another function that expects an Int, but then you will get a similar exception except that the expected will be a non-function (Int) for example, and the actual type is a function, so something like:
• Couldn't match expected type ‘Int’
with actual type ‘Integer -> t’
Haskell's type system will thus error in case you call a function with too much arguments, or when you use the result of a function with too few arguments.
Note that strictly speaking in Haskell every function only takes one parameter. If you do not provide one, then the outcome is still a function, if you provide one, you make a function call, but that function can produce another function thus expects the next parameter.
The reason that printf can take one, two, or more parameters, is because of the instances of the PrintfType type class. This can be an IO a that will thus then print the result of the formatted string, or a function (PrintfArg a, PrintfType r) => a -> r that thus will take a parameter of the PrintfArg type, and return another PrintfType type. It can thus each time specialize in an extra function if another function is necessary. But this thus emulates a variadic function, where you can pass an arbitrary number of parameters.
It seems that in certain situations you can call functions with labeled arguments without the labels if they're in the right order; e.g.
let f ~x ~y = Format.sprintf "%d %s" x y;;
f 3 "test";;
runs successfully, but
f "test" 3;;
fails with the error message
Line 1, characters 2-8:
Error: This expression has type string but an expression was expected of type
int
For functions with optional arguments, it seems to work if you don't pass in the optional arguments:
let f ?(x = 1) ~y () = Format.sprintf "%d %s" x y;;
f "help" ();;
succeeds, but
f 2 "help" ();;
fails with the error message
Line 1, characters 4-10:
Error: The function applied to this argument has type
?x:int -> y:string -> string
This argument cannot be applied without label
Is there a general rule for when this is possible?
You can omit labels if the application is total (i.e., all required arguments are provided) and if the return type of the function is not a type variable. Arguments to the optional parameters must always be passed by a label.
Let's do some examples,
let example1 ?(opt=0) ~a ~b ~c unlabeled =
opt + a + b + c + unlabeled;;
example1 1 2 3 4;;
- : int = 10
Here we were able to apply all arguments without labels, because we have provided all required arguments (the optional parameter is not required, hence the name), and the resulting type is not polymorphic. However, if we will take the List.fold function from Core or ListLabels, which has type
'a list -> init:'accum -> f:('accum -> 'a -> 'accum) -> 'accum
Then we will get,
List.fold [1;2;3;4] 0 (+);;
- : init:(int -> (int -> int -> int) -> '_weak1) ->
f:((int -> (int -> int -> int) -> '_weak1) ->
int -> int -> (int -> int -> int) -> '_weak1) ->
'_weak1
instead of 10, which one would expect. The reason for that is since the resulting type 'accum is a type variable, so it could also be a function, e.g., int -> int or string -> int -> unit, etc -- all those types match with the 'accum type. That basically means that this function accepts a potentially infinite number of positional arguments. Therefore, all arguments that we provided were interpreted as positional, and as a result, we never were able to fill in the labeled arguments, therefore, our application wasn't made total. This actually makes our original definition of the rule at the beginning of the posting redundant - since an application, which type is denoted with a type variable, could never be total.
Note, that this problem only occurs when the return type is a type variable, not just includes some type variables, for example, we can easily omit labels with the List.map function, e.g, given List.map from Core, which has type
'a list -> f:('a -> 'b) -> 'b list
we can easily apply it
# List.map [1;2;3] ident;;
- : int Core_kernel.List.t = [1; 2; 3]
With all that being said, it is usually assumed a bad practice to omit the labels. Mainly because of the caveats with polymorphic return types and because it makes the order of the labeled arguments important, which is sort of counter-intuitive.
Yes, there is a general rule for this. From the manual:
Formal parameters and arguments are matched according to their respective labels, the absence of label being interpreted as the empty label. This allows commuting arguments in applications. One can also partially apply a function on any argument, creating a new function of the remaining parameters.
If several arguments of a function bear the same label (or no label), they will not commute among themselves, and order matters. But they can still commute with other arguments.
As an exception to the above parameter matching rules, if an application is total (omitting all optional arguments), labels may be omitted. In practice, many applications are total, so that labels can often be omitted.
Imagine I have a custom type and two functions:
type MyType = Int -> Bool
f1 :: MyType -> Int
f3 :: MyType -> MyType -> MyType
I tried to pattern match as follows:
f1 (f3 a b i) = 1
But it failed with error: Parse error in pattern: f1. What is the proper way to do the above?? Basically, I want to know how many f3 is there (as a and b maybe f3 or some other functions).
You can't pattern match on a function. For (almost) any given function, there are an infinite number of ways to define the same function. And it turns out to be mathematically impossible for a computer to always be able to say whether a given definition expresses the same function as another definition. This also means that Haskell would be unable to reliably tell whether a function matches a pattern; so the language simply doesn't allow it.
A pattern must be either a single variable or a constructor applied to some other patterns. Remembering that constructor start with upper case letters and variables start with lower case letters, your pattern f3 a n i is invalid; the "head" of the pattern f3 is a variable, but it's also applied to a, n, and i. That's the error message you're getting.
Since functions don't have constructors, it follows that the only pattern that can match a function is a single variable; that matches all functions (of the right type to be passed to the pattern, anyway). That's how Haskell enforces the "no pattern matching against functions" rule. Basically, in a higher order function there's no way to tell anything at all about the function you've been given except to apply it to something and see what it does.
The function f1 has type MyType -> Int. This is equivalent to (Int -> Bool) -> Int. So it takes a single function argument of type Int -> Bool. I would expect an equation for f1 to look like:
f1 f = ...
You don't need to "check" whether it's an Int -> Bool function by pattern matching; the type guarantees that it will be.
You can't tell which one it is; but that's generally the whole point of taking a function as an argument (so that the caller can pick any function they like knowing that you'll use them all the same way).
I'm not sure what you mean by "I want to know how many f3 is there". f1 always receives a single function, and f3 is not a function of the right type to be passed to f1 at all (it's a MyType -> MyType -> MyType, not a MyType).
Once a function has been applied its syntactic form is lost. There is now way, should I provide you 2 + 3 to distinguish what you get from just 5. It could have arisen from 2 + 3, or 3 + 2, or the mere constant 5.
If you need to capture syntactic structure then you need to work with syntactic structure.
data Exp = I Int | Plus Exp Exp
justFive :: Exp
justFive = I 5
twoPlusThree :: Exp
twoPlusThree = I 2 `Plus` I 3
threePlusTwo :: Exp
threePlusTwo = I 2 `Plus` I 3
Here the data type Exp captures numeric expressions and we can pattern match upon them:
isTwoPlusThree :: Exp -> Bool
isTwoPlusThree (Plus (I 2) (I 3)) = True
isTwoPlusThree _ = False
But wait, why am I distinguishing between "constructors" which I can pattern match on and.... "other syntax" which I cannot?
Essentially, constructors are inert. The behavior of Plus x y is... to do nothing at all, to merely remain as a box with two slots called "Plus _ _" and plug the two slots with the values represented by x and y.
On the other hand, function application is the furthest thing from inert! When you apply an expression to a function that function (\x -> ...) replaces the xes within its body with the applied value. This dynamic reduction behavior means that there is no way to get a hold of "function applications". They vanish into thing air as soon as you look at them.
cube (x,y,z) =
filter (pcubes x) cubes
cubes = [(a,b,c) | a <- [1..30],b <- [1..30],c <- [1..30]]
pcubes x (b,n,m) = (floor(sqrt(b*n)) == x)
so this code works, cubes makes a list of tuples,pcubes is used with filter to filter all the cubes in which floor(sqrt(b*n)) == x is satisfied,but the person who has modified my code wrote pcubes x in filter (pcubes x) cubes,how does this work.pcubes x makes a function that will initial the cubes x (b,n,m) that will take in a tuple and output a bool.the bool will be used in the filter function. How does this sort of manipulation happen? how does pcubes x access the (b,n,m) part of the function?
In Haskell, we don't usually use tuples (ie: (a,b,c)) to pass arguments to functions. We use currying.
Here's an example:
add a b = a + b
Here add is a function that takes a number, the returns another function that takes a number, then returns a number. We represent it's type as so:
add :: Int -> (Int -> Int)
Because of the way -> behaves, we can remove the parentheses in this case:
add :: Int -> Int -> Int
It is called like this:
(add 1) 2
but because of the way application works, we can just write:
add 1 2
Doesn't that look like our definition above, of the form add a b...?
Your function pcubes is similar. Here's how I'd write it:
pcubes x (b,n,m) = floor (sqrt (b*n)) == x
And as someone else said, it's type could be represented as:
pcubes :: Float -> (Float, Float, Float) -> Bool
When we write pcubes 1 the type becomes:
pcubes 1 :: (Float, Float, Float) -> Bool
Which, through currying, is legal, and can quite happily be used elsewhere.
I know, this is crazy black functional magic, as it was for me, but before long I guarantee you'll never want to go back: curried functions are useful.
A note on tuples: Expressions like (a,b,c) are data . They are not purely function-argument expressions. The fact that we can pull it into a function is called pattern matching, though it's not my turn to go into that.
In Haskell, I know that if I define a function like this add x y = x + y
then I call like this add e1 e2. that call is equivalent to (add e1) e2
which means that applying add to one argument e1 yields a new function which is then applied to the second argument e2.
That's what I don't understand in Haskell. in other languages (like Dart), to do the task above, I would do this
add(x) {
return (y) => x + y;
}
I have to explicitly return a function. So does the part "yields a new function which is then applied to the second argument" automatically do underlying in Haskell? If so, what does that "hiding" function look like? Or I just missunderstand Haskell?
In Haskell, everything is a value,
add x y = x + y
is just a syntactic sugar of:
add = \x -> \y -> x + y
For more information: https://wiki.haskell.org/Currying :
In Haskell, all functions are considered curried: That is, all functions > in Haskell take just single arguments.
This is mostly hidden in notation, and so may not be apparent to a new
Haskeller. Let's take the function
div :: Int -> Int -> Int
which performs integer division. The expression div 11 2
unsurprisingly evaluates to 5. But there's more that's going on than
immediately meets the untrained eye. It's a two-part process. First,
div 11
is evaluated and returns a function of type
Int -> Int
Then that resulting function is applied to the value 2, and yields 5.
You'll notice that the notation for types reflects this: you can read
Int -> Int -> Int
incorrectly as "takes two Ints and returns an Int", but what it's
really saying is "takes an Int and returns something of the type Int
-> Int" -- that is, it returns a function that takes an Int and returns an Int. (One can write the type as Int x Int -> Int if you
really mean the former -- but since all functions in Haskell are
curried, that's not legal Haskell. Alternatively, using tuples, you
can write (Int, Int) -> Int, but keep in mind that the tuple
constructor (,) itself can be curried.)