2015-02-02 3 views
-4

Что такое подпись следующей функции Haskell:Haskell неподвижная точка подписи

fix f = f (fix f) 

а) ((а-> Ь) -> а-> Ь) -> а-> б

б) подписи не могут быть синтезированы

с) (а-> а) -> а

Спасибо!

+5

Вы можете попробовать положить это в REPL и посмотреть сами. – Sibi

+4

Более конкретно определите 'fix' в GHCi с помощью' let fix f = f (fix f) ', а затем попросите его тип с помощью:: t fix. – phadej

+4

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

ответ

6

Этот вопрос выглядит как домашнее задание/тестовый вопрос. Я порекомендую вам найти решение самостоятельно:

Сначала у вас, вероятно, установлен GHC, поэтому вы можете запустить ghci реплика haskell.

a section in GHC users' guide about GHCi. Но это довольно долго.

Если вы запускаете GHCI вы получите подсказку, где вы можете ввести Haskell выражения:

Prelude> 1 + 1 
2 
Prelude> map (\x -> x + x) [1, 2, 3] 
[2,4,6] 

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

Prelude> let fix f = f (fix f) 

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

Prelude> :t map (\x -> x + x) 
map (\x -> x + x) :: Num b => [b] -> [b] 
Prelude> :t fix 
... output omitted 

Tha t, как вы находите решение своей проблемы. После того, как вы это знаете, вы можете спросить, почему тип fix является тем, чем он является.

2

Совершенно другой подход: поиск решения посредством рассуждений.

Правая рука

f (fix f) 

так f имеет тип a -> b для некоторых типов a и b, так как f функция.

Иными словами, значение f (fix f) имеет тип b, а fix f имеет тип a.

Так как, по определению,

fix f = f (fix f) 

fix f должны иметь тот же тип, как f (fix f), т.е. b.

Мы уже говорили, что a является тип fix f, так a и b должны быть того же типа.

Назовем его t, чтобы все было в порядке.

Так f : t -> t, поскольку a и b были такого же типа t.
Мы знаем, что fix f имеет тип b, который мы переименовали в t.

Ввод f : t -> t и fix f : t вместе мы получаем

fix : (t -> t) -> t 

, который является альтернативой с).


В сторону: если мы подставим a -> b для t мы получаем

((a -> b) -> (a -> b)) -> (a -> b) 

или, так как стрелка правоассоциативным на:

((a -> b) -> a -> b) -> a -> b 

это именно ответ в).
Итак, а) почти правильно, но недостаточно общего.

+0

Почему вы не останавливаетесь на 'fix :: (t -> t) -> t'. Это правильный и основной тип HM, который равен (по модулю переименованию) на * c) *. Я бы сказал, что оба * a) * и * c) * верны, если вопрос является множественным выбором. Или тогда любой из них в порядке (любой правильный тип). – phadej

+1

@phadej Я действительно останавливался там, но я редактировал, чтобы надеяться сделать это немного яснее, чем я. В конце концов, чтобы объяснить, что альтернатива а) недостаточно общего. – molbdnilo

Смежные вопросы