2010-07-03 4 views
0

Хорошо, на этот раз я проясню, задача функции1 - проверить строку, если она появляется с символом '?' вещь, он поместит остальную часть строки в список. если нет, то он будет хранить все в стеке, как я могу это сделатьХранение данных в таблице в Haskell

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 
+1

Если вы хотите, чтобы ваша функция возвращала другой тип, сделайте его возвратом другого типа. Если 'function2' не возвращает' b', вам нужно написать функцию для преобразования вывода функции 'function2' в нечто вроде' b', а затем применить ее к 'function2'. – jrockway

+0

нет, нет, нет, должен быть какой-то способ обойти это возвращение, например, написать что-то еще вокруг функции2, которая вернет b, но функция2 все равно будет выполнять свою работу – Rn2dy

+3

ну, это именно то, что предлагает jrockway. Просто напишите 'function3 :: a -> b' с' function3 x = SomeB' и используйте 'function3 (function2 xs)' в вашей первой функции. – tonio

ответ

4

Во-первых, пожалуйста, используйте Data.Map для хранения словаря вместо списка кортежей, чтобы избежать поиска O (N).

Функции Haskell чисты, то есть вы не должны иметь изменяемые состояния. Если вам нужно что-то «хранить», оно должно появиться в списке аргументов, например.

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 

В качестве альтернативы, вы можете использовать монадические вещи, как Data.STRef и Data.IORef использовать изменяемые переменные, но какая-то часть вашего кода должны быть обернута в монаде ST или IO без необходимости.

+0

да, это именно то, что мне нужно сделать, большое вам спасибо! – Rn2dy

1

Appparently вы хотите бросить строку ([Char]) в чем-то | что-нибудь. Это не сработает. Формальная причина: fun :: a-> b невозможно, так как b должно происходить где-то в аргументах, иначе оно не вычитается. Неформально: вы не можете обеспечить безопасность. Пример: ваш [Char] == «Hello world», и вы пытаетесь включить его в Int. BTW cast - это C-talk для typeconversion.

1

Дело в том, что если x == '?', С тем, как вы его написали, функция1 вернется так же, как function2. И если функция2 ничего не возвращает, то функция1 сделает это.

Поскольку трудно определить, что вы хотите сделать, короткий ответ - нет!

Но не сдавайтесь! в любом случае есть вещи, которые вы можете сделать, которые на самом деле довольно приятные. в первую очередь, если вы просто хотите знать, что возвращает функция2, а в случае , что x является?? вернуть что-то еще для function1 вы делаете так:

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

    where fun2Returns = function2 xs 

Теперь давайте предположим, что вы хотите, чтобы что-нибудь (Thats return null в С-говорить) не возвращаются, вы должны быть четко о том, что в вас типа, с помощью тип Maybe.

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

Что-то вроде?

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

function2 :: [Char] -> Maybe b 

Update:

Это не выглядит право (x :: String, но не Maybe a)

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

Я предполагаю, что это должно выглядеть примерно так:

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