mehdix_
mehdix_

Reputation: 479

defining type within lambda function

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

Answers (2)

Ganesh Sittampalam
Ganesh Sittampalam

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

chi
chi

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

Related Questions