Reputation: 479
Is there any way I could define a type for an input variable for a lambda function. I've got this as a function
bstar :: Language -> Int -> Language
bstar l n =
case l of
[] -> zero
l -> case n of
0 -> [[]]
n -> (\pow l n -> if n == 0
then [[]]
else l `cat` (pow l (n-1))) l n `uni` (bstar l (n-1))
when I compile this in haskell I get mismatch type error 'Int' with 'String'. I was wondering if there's any way I could define the input variable of lambda function "pow" l as a Language. Any Idea?
Upvotes: 0
Views: 389
Reputation: 29100
You can use the ScopedTypeVariables
language extension to enable this syntax:
\(x :: Int) -> x
You enable the extension either with -XScopedTypeVariables
on the GHC command-line, or by putting
{-# LANGUAGE ScopedTypeVariables #-}
at the top of the source file.
As I noted in a comment on the question, this may not actually help fix your error. For a lot of straightforward Haskell code including yours, adding a type signature won't actually make the code typecheck when it didn't otherwise. What it will do is make it much easier to locate the type error as it'll become clear to you where your intentions and what the compiler inferred differ.
EDIT following discussion in comments:
The problem with your code is that you're trying to define a recursive function pow
with just a lambda, which isn't directly possible. Your lambda expects a function pow
as an argument, but you're not passing one.
As @chi's answer and comment notes, your code would probably be cleanest with a where
clause instead, but you can also do this with fix
if you really want to keep the inline lambda.
It has the following type and definition:
fix :: (a -> a) -> a
fix f = let x = f x in x
In this case, the a
type will be the desired type of your pow
function, i.e. (Language -> Int -> Language)
. So fix
will end up turning your lambda into a recursive definition - x
in the definition of fix
corresponds to your pow
.
bstar :: Language -> Int -> Language
bstar l n =
case l of
[] -> zero
l -> case n of
0 -> [[]]
n -> fix (\pow l n ->
if n == 0
then [[]]
else l `cat` (pow l (n-1))) l n `uni` (bstar l (n-1))
You may need to add this at to your imports at the top of the module:
import Data.Function (fix)
You can look at this question for more discussion of fix
.
Upvotes: 5
Reputation: 116139
Probably you are looking for something like this:
bstar :: Language -> Int -> Language
bstar l n =
case l of
[] -> zero
l -> case n of
0 -> [[]]
n -> pow l n `uni` bstar l (n-1)
where pow :: Language -> Int -> Language
pow l n = if n == 0
then [[]]
else l `cat` pow l (n-1)
Let me "restyle" a bit your code, hopefully making it clearer.
bstar :: Language -> Int -> Language
bstar [] _ = zero
bstar _ 0 = [[]]
bstar l n = pow l n `uni` bstar l (n-1)
where pow :: Language -> Int -> Language
pow _ 0 = [[]]
pow l n = l `cat` pow l (n-1)
Upvotes: 4