0

Okay, this time I'll make it clear, the job of function1 is to check a string if it comes up with the '?' thing, he will put the rest of the string in a list. if not, it will store everything in a stack, how can I do this

function2 :: [String] -> [([Char], [Integer]->[Integer])] 
function1 :: [String] -> [Integer] -> ([Integer], String)
function1 [] stack = (stack, "")
function1 (x:xs) stack 
     | x == "?"           = function2 xs  -- # map the tokens after '?' to functions
                                          -- # and put them into dictionary for 
                                          -- # function1's later use
     | x == "m"           = function1 xs ((read x :: b):stack)
     | x == isJust lookup = eval xs (f stack)
     ...
     where lookup = -- # lookup(f) is the function that is mapped from the token x
8
  • 1
    If you want your function to return a different type, then make it return a different type. If function2 doesn't return b, then you need to write a function to convert the output of function2 to something of type b, and then apply it to function2. Commented Jul 3, 2010 at 5:19
  • no,no,no, there must be some way to bypass this return, like write something else around function2 that will return b, but function2 will still do his own job Commented Jul 3, 2010 at 5:27
  • 3
    well, this is exactly what jrockway proposes. Just write a function3 :: a -> b with function3 x = SomeB, and use function3 (function2 xs) in your first function. Commented Jul 3, 2010 at 6:16
  • Downvoted. I can't understand what you are trying to achieve. For some guesses the answer is trivial, and for others its impossible. Commented Jul 3, 2010 at 7:25
  • Functions in Haskell are pure. The only "job" for function2 is to return a value based upon its input. There should be no side-effects, input, output, or anything else. If function2 is supposed to do something like that then it needs to be in the appropriate monad (e.g. IO). The standard idiom for this is to return (), or IO () (similar to void in C). Commented Jul 3, 2010 at 12:08

4 Answers 4

4

Firstly, please use a Data.Map to store the dictionary instead of a list of tuples to avoid O(N) look-up.

Haskell functions are pure, i.e. you shouldn't have mutable states. If you need to "store" something, it must appear in the argument list, e.g.

import qualified Data.Map as M

type Stack = [Integer]
type StackFunction = Stack -> Stack
type Token = String
type TokenMap = M.Map Token StackFunction
function2 :: [Token] -> TokenMap

function1_alt :: TokenMap -> [Token] -> Stack -> (Stack, Token)
function1_alt _ [] stack = (stack, "")
function1_alt map ("?":xs) stack = let newMap = function2 xs in
                                       function1_alt (M.union oldMap newMap) xs stack
-- #          pass the new changed map as an argument ^^^^^^^^^^^^^^^^^^^^^
function1_alt map ("m":xs) stack = function1_alt map xs ((read x):stack)
function1_alt map (x:xs) stack | isJust f  = eval xs (fromJust f $ stack)
                               | otherwise = ...
                              where f = M.lookup x map

function1 :: [Token] -> Stack -> (Stack, Token)
function1 = function1_alt M.empty

Alternatively, you could use monadic things like Data.STRef and Data.IORef to use mutable variables, but then some part of your code need to be wrapped in an ST or IO monad unnecessarily.

Sign up to request clarification or add additional context in comments.

Comments

1

Appparently you want to cast a String ([Char]) into something|anything. That won't work. Formal reason: fun::a->b is not possible as b must occur somewhere in the arguments, otherwise it is not deductible. Informally: you cannot insure typesafety. Ex: your [Char] == "Hello world" and you attempt to cast it into a Int. BTW cast is C-speak for typeconversion.

Comments

1

The thing is that if x == '?', with the way that you have written it, function1 will return the same as function2. And if function2 returns nothing then function1 will do so to.

Since It's hard to deduce what you want to do, the short answer is no!

But don't give up! in any case there are things you can do that are actually quite nice. first of if you just want to know what function2 returns, and in the case that x is '?' return something else for function1 you do like this:

function1 (x:xs) 
          | x == '?' = somethingElse
          | x == '3' = do something with fun2Returns        
        ...

  where  fun2Returns = function2 xs

Now let's say that you want that to not return anything (thats return null in c-speak), you have to be explicit about that in you types, by using the Maybe type.

function1 :: String -> Maybe b
function1 (x:xs)
          | x == '?' = Nothing

Comments

1

Something like?

function1 :: [Char] -> b
function1 (x:xs)
  | x == '?' && isJust r = fromJust r where r = function2 xs

function2 :: [Char] -> Maybe b

Update:

That doesn't look right (x :: String, but not Maybe a)

 ...
 | x == isJust lookup = eval xs (f stack)
 ...
 where lookup = -- # lookup(f) is the function that is mapped from the token x

I guess it should look something like:

 ...
 | maybe False (x ==) lookup = eval xs (f stack)
 ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.