Вопрос для новичков: проблемы с использованием функции в каждой комбинации двух списков произвольного типа - PullRequest
1 голос
/ 05 августа 2020

В настоящее время я готовлюсь к экзамену по университетскому курсу начального уровня, в котором мы используем Haskell в основном для моделирования комбинационных схем. У меня есть основные c проблемы с самим Haskell, почти ничего не зная о функциональном программировании и исходящий из базового c уровня понимания Java, что еще больше усложняет ситуацию.

Я пытаюсь создать функцию, которая использует и печатает все комбинации двух списков моего настраиваемого типа в компараторе. Я работаю со следующими (работающими по назначению) фрагментами:

type Nibble = (Bool, Bool, Bool, Bool) 
comparator :: Nibble -> Nibble -> Bool 
comparator (a3,a2,a1,a0) (b3,b2,b1,b0) = nor [a3<+>b3, a2<+>b2, a1<+>b1, a0<+>b0]

Используя понимание списка, я получил список, содержащий все 4 кортежа моего настраиваемого типа. Я пытаюсь использовать каждый элемент своих двух списков, чтобы получить результат компаратора для каждой возможной комбинации моего настраиваемого типа.

Я попытался создать функцию, которая берет заголовок каждого из двух списков и использует их с функция компаратора, чтобы затем рекурсивно начать с остальной части списка. Я борюсь практически со всеми частями этой функции, и я думаю, что иду по неправильному пути.

Я ищу ресурсы, которые могут указать мне правильное направление / правильные концепции, на которые мне нужно взглянуть, и возможно, предложение о том, как мне подходить к подобным проблемам, поскольку я борюсь с концепцией функционального программирования и объединения нескольких функций. Понятия не имею, с чего и как начать. Я работаю с Learnyoua haskell, однако они, кажется, очень быстро переходят от очень простых к довольно сложным примерам, пропуская большинство тем, которые мне нужны.

Я был бы очень признателен, если бы кто-нибудь мог указать мне направление. Заранее большое спасибо! Извините, пожалуйста, за недостатки в описании моей проблемы. Я впервые пишу что-нибудь о stackoverflow. Я проясню все, что я пропустил в правках. понимание необходимой терминологии.

Функция компаратора предназначена для моделирования схемы компаратора, проверяя, совпадают ли два 4-битных числа, представленные здесь полубайтами. Я собираюсь опробовать эту функцию на каждой возможной комбинации двух 4-битных чисел. Моя идея заключалась в том, чтобы составить список nibTab = [(a,b,c,d) | a <- [False, True], b <- [False, True],c <- [False, True],d <- [False, True]], используя его как входной список 1 и входной список 2. Предполагается, что оба списка будут выглядеть следующим образом, что, как мне кажется, я уже достиг: [(True, True, True, True), (True,True,True,False),...,(False,False,False,False)]

Я пытаюсь напечатать строку для каждого сравнения, и с двумя ответами она действительно заработала.

compRow :: [String]  
compRow =  
  [show x ++ " , " ++ show y ++ " : " ++ show (comparator x y)  
  | x <- nibTab, y <- nibTab]  
  where  
    nibTab = [(a,b,c,d) | a <- [False, True], b <- [False, True],c <- [False, True],d <- [False, True]]  

compList :: [String] -> String  
compList [] = ""  
compList (x:xs) = show x ++ "\n" ++ compList xs  

У меня был меньший пример для работы. Здесь мы проверили, работает ли наше определение XOR-оператора должным образом. Я заблудился, пытаясь определить, как должны выглядеть подписи типов для моей задачи, и написал соответствующие функции, которые пытались имитировать пример ниже:

(<+>) :: Bool -> Bool -> Bool
(<+>) a b = (a || b) && (not (a && b))

table_row :: (Bool -> Bool -> Bool) -> (Bool, Bool) -> String
table_row f (x, y) = show (x,y)++ ":" ++ show (f x y)

table :: (Bool -> Bool -> Bool) -> [(Bool, Bool)] -> String
table f [] = ""
table f (x:xs) =  table_row f x ++ "\n" ++ table f xs

checkTable = do
  let bool_duo [(a,b) | a <- [False,True], b <- [False,True]]
  putStrLn (table (<+>) bool_duo)

Ответы [ 2 ]

1 голос
/ 06 августа 2020

Трудно понять, что вы хотите сделать, но я предполагаю что-то вроде этого:

bools = [True, False]
all_nibbles = [(a,b,c,d) | a <- bools, b <- bools, c <- bools, d <- bools]
all_results = [comparator x y | x <- all_nibbles, y <- all_nibbles]

Этот код использует понимание списка, чтобы сначала создать список всех возможных полубайтов, а затем вычислить результаты вашей функции при применении ко всем возможным комбинациям полубайтов.

Для дальнейшего использования:

  • в Haskell, (a,b,c,d) - кортеж:
    • кортежи имеют фиксированную длину, и
    • каждый элемент кортежа может иметь другой тип.
  • в Haskell, [a,b,c,d] - это список:
    • списки имеют переменную длину, и
    • каждый элемент списка должен иметь один и тот же тип
1 голос
/ 05 августа 2020

Вы уже видели составления списка. Вы можете использовать это для вызова функции со всеми элементами в уже имеющемся списке. Например,

results :: [String]
results = 
   [ "The square of " ++ show x ++ " is " ++ show (square x)
   | x <- allInputs ]
   where
   square y  = y*y
   allInputs = [0..10]  -- an example

Выше, square имеет только один аргумент. Если у вас есть больше, добавьте генератор к пониманию списка.

results :: [String]
results = 
   [ "The comparison of " ++ show x ++ " and " ++ show y
     ++ " is " ++ show (comparator x y)
   | x <- allInputs, y <- allInputs ]
   where
   allInputs = ....  -- your list with all the inputs to try

Если вам не нужен список строк, адаптируйте его соответствующим образом.

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