Ваша функция combinations
уже создает список списков длиной n
, содержащий все возможные перестановки True
и False
. Вы не должны использовать concat
; результат уже включает в себя все возможные записи в вашей функции. Это так, потому что проверяемая функция уже ожидает список (в форме \[a,b,c...]
).
То есть для fn
со списком длины 3 combinations 3
будет:
[[True,True,True],[True,True,False],[True,False,True],[True,False,False],
[False,True,True],[False,True,False],[False,False,True],[False,False,False]]
Каждый элемент этого списка представляет собой список ; вы можете передать их в проверяемую вами функцию (ту, которая может быть тавтологией) напрямую. Учитывая приведенный выше список, все, что вам нужно сделать, это попробовать каждый элемент.
РЕДАКТИРОВАТЬ (пытается уточнить немного):
Требуется функция taut
, которая принимает другую функцию типа [Bool] -> Bool
и определяет, является ли эта функция тавтологической. Это означает, что taut
будет иметь тип, подобный Int -> ([Bool] -> Bool) -> Bool
. Допустим, вы начинаете это так:
taut :: Int -> ([Bool] -> Bool) -> Bool
taut n fn = ...
Теперь n
- это длина, а fn
- это функция. Ваша combinations
функция принимает n
и возвращает каждый возможный действительный ввод в fn
. Обратите внимание, что fn
ожидает [Bool]
, а combinations n
- [[Bool]]
, что означает, что каждый элемент может быть входом для fn
. Зная это, все, что вам нужно сделать, это применить fn
к каждому элементу combinations n
и посмотреть, всегда ли результат одинаков.
В вашей функции taut
вам не нужно беспокоиться о назначении переменных внутри тестируемой функции. Когда вы на самом деле пишете эту функцию, если она будет иметь вид \[x,y,z]->...
,
,
y
и
z
будут назначены внутри нее благодаря сопоставлению с образцом. *1052*