Хранение данных в таблице в Haskell - PullRequest
0 голосов
/ 03 июля 2010

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

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

Ответы [ 4 ]

4 голосов
/ 03 июля 2010

Во-первых, пожалуйста, используйте 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.

1 голос
/ 03 июля 2010

Дело в том, что если x == '?', То, как вы это написали, function1 вернет то же самое, что и function2.И если function2 ничего не возвращает, то function1 сделает это для.

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

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

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

  where  fun2Returns = function2 xs

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

function1 :: String -> Maybe b
function1 (x:xs)
          | x == '?' = Nothing
1 голос
/ 03 июля 2010

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

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

function2 :: [Char] -> Maybe b

Обновление:

Это выглядит не так (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)
 ...
1 голос
/ 03 июля 2010

Очевидно, что вы хотите наложить String ([Char]) на что-нибудь | что угодно.Это не сработает.Формальная причина: fun :: a-> b невозможна, поскольку b должно присутствовать где-то в аргументах, в противном случае оно не выводитсяНеформально: вы не можете застраховать безопасность типов.Пример: ваш [Char] == "Hello world", и вы пытаетесь привести его к Int.Кстати, приведение C-говорить для преобразования типов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...