2013-05-22 2 views
0

я должен реализовать пример функции с следующей подписью:Haskell - реализовать функцию для данной подписи

[[([Char], a, b)]] -> (a -> b -> Char) -> ([Char], b -> a -> Char) 

Так я пытаюсь так:

funcD [[([' '],x,y)]] uFunc0D = ([' '], uFunc1D) 
    where 
     uFunc0D x y = ' ' 
     uFunc1D y x = ' ' 

но Whe я призываю тип его с

:t funcD 

возвращает

funcD :: [[([Char], t1, t2)]] -> t -> ([Char], t3 -> t4 -> Char) 

Несколько вопросов:

  1. Почему не возвращает t для 2-го аргумента, а не (a -> b -> Char)?
  2. Я передал ' ' для Char, но он работает, однако я хочу передать пустой char-arg, как '', но он не работает.
  3. Почему я получаю t3 и t4, а не t1 и t2 в сигнатуре результата?

Заранее спасибо

Edit: Моя следующая попытка:

funcD1 [[([' '],x,y)]] (uFunc0D x y = ' ' where _ = x y) = ([' '], uFunc1D) 
    where 
     uFunc1D y x = ' ' 
+3

Вместо того, чтобы бросать синтаксис на стену и видеть, какие палки, я предлагаю вам изучить синтаксис Haskell. Например, попробуйте [эту главу «Learn You a Haskell») (http://learnyouahaskell.com/syntax-in-functions). В частности, обратите внимание на разницу между шаблонами и выражениями и какие из них идут туда. – hammar

ответ

4
  1. uFunc0D не используется (вы теневые аргумент в предложении where с функцией, которая имеет одинаковое имя)
  2. ' ' обозначает символьный символ, он должен содержать один символ. Возможно, вы думаете о строках, и в этом случае "" - пустая строка.
  3. Аргументы к uFunc1D никак не связаны с входными аргументами x и y, поэтому они могут быть разных типов.

Edit:

вы должны использовать аргументы в выражении (справа от знака равенства) для того, чтобы повлиять на тип возвращаемого значения. Ваша декларация в предложении where содержит uFunc0D и uFunc1D. Объявление uFunc0D затеняет привязку uFunc0D в аргументе (слева) функции, так что , даже если вы должны указать uFunc0D в формате rhs, это будет тот, который вы объявили в предложении where, а не аргумент ,

Edit 2:

Вот пример, скажем, вы хотите функцию f :: (a -> b) -> a -> Char

Наивная попытка может быть: f f1 x = ' ', но это будет иметь тип f :: a -> b -> Char. Поскольку факт, что f1 должен быть функцией, неизвестен (и на самом деле вы можете передать что-то еще как f1), и тот факт, что он принимает что-то типа того же типа, что и второй аргумент, также неизвестен.

Вместо этого, если вы делаете: f f1 x = ' ' where _ = f1 x, тогда тип будет f :: (a -> b) -> a -> Char. В этом случае компилятор знает, что f1 должен принимать хотя бы один аргумент (поскольку вы применяете его к аргументу), а аргумент должен иметь тип второго аргумента (поскольку вы применяете его ко второму аргументу).

Edit 3:

Слово о синтаксисе Haskell.

Функция декларации выглядит следующим образом: f arg1 arg2 = expr

, что входит в положение arg1 и arg2 являются образцами. то, что происходит в expr, являются выражениями.

если вы видите что-то вроде

f x = y 
    where y = x + 1 

, что предшествует пункт where это выражение, и то, что следует за ним в декларации видны в выражении. Символы новой строки перед маркером where несущественны, вышесказанное идентично f x = y where y = x + 1.

Что такое шаблоны? Шаблоны позволяют разлагать значение на части и связывать детали с именами.

x - это шаблон, в id x = x, например. Это означает, что x привязан к первому аргументу id. x с правой стороны - не шаблон, а выражение, одно со значением x, которое было связано с шаблоном с левой стороны.

(a, b) - другой рисунок, как в fst (a, b) = a. Этот шаблон указывает, что тип ввода должен быть 2-кортежем, причем первый элемент привязан к a, а второй привязан к b.

В mkPair a b = (a, b), (a, b) это выражение, а не образец. Это выражение, которое имеет значение 2-кортежа, первым элементом которого является a (связанный как первый аргумент в левой части), и второе значение b (связанное как второй аргумент с правой стороны).

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

+0

спасибо за сообщение. 1. Если uFunc0D затенен, uFunc1D также должен быть затенен, так как оба находятся в разделе where. Но, как вы видите, он возвращает полную подпись для uFunc1D, но не для uFunc0D. Я также попытался написать 'uFunc0D x y = ''' непосредственно как параметр без 'where', но, конечно, он не работает. 3. В требуемой подписи находятся 'a' и' b'every, где то же самое. Не могли бы вы рассказать мне, как я могу исправить эти проблемы, чтобы получить ту же подпись? – John

+0

Я не уверен, правильно ли я вас понимаю, но uFunc0D - входной аргумент.Как мне поместить его в правую часть уравнения? Правая сторона - это часть возврата. Не могли бы вы объяснить, что вы имеете в виду? – John

+0

Отредактировано снова (надеюсь) полезным примером. – yiding