[haskell] как описать заголовок функции

yroslavasako

Пробовал научиться пользоваться функциями высшего порядка. Есть функция, которая берёт другую функцию, применяет в двум аргументам и сравнивает. У меня не получилось правильно объявить её тип.
Что есть сейчас:

testMean :: Eq a => (b->a) -> b -> b -> Bool
testMean k x y = (k x) == (k y)

Этот вариант не работает, например для сравнения вызова

x = [1..4]
y = "code"
z = testMean length x y

Ivan8209

> Пробовал научиться пользоваться функциями высшего порядка.
> У меня не получилось правильно объявить её тип.
Чего-то я не пойму, а куда вывод типа делся?
В хаскеле его отменили?

Standard ML of New Jersey v110.71 [built: Wed Oct 21 09:12:13 2009]
- fun testmean k x y = k(x) = k(y);
stdIn:1.27 Warning: calling polyEqual
val testmean = fn : ('a -> ''b) -> 'a -> 'a -> bool

---
...Я работаю антинаучным аферистом...

alfadred

Ну у тебя тип [1..4] не совпадает с типом "abcd", а в описании на этом месте стоит одна и та же переменная типа.
Скорее всего, тебе надо
{-# LANGUAGE RankNTypes #-}
testMean :: (Eq a) => (forall x. f x -> a) -> f b -> f c -> Bool

По крайней мере, на тестовом примере работает.

yroslavasako

Ну у тебя тип [1..4] не совпадает с типом "abcd", а в описании на этом месте стоит одна и та же переменная типа.
Это я понял. А как от этого избавиться? Твой пример даже на интах и id не работает

alfadred

Это я понял. А как от этого избавиться? Твой пример даже на интах и id не работает
Мой пример работает на length и списках.

alfadred

Это я понял. А как от этого избавиться?
Поставить там разные переменные типа, ы?
Т.е. должно быть что-то типа
(Eq a) => (здесь тип функции) -> b -> c -> Bool

При этом тип функции должен быть применим к любому типу, т.е это должно быть (forall x. x -> a но с length это работать не будет, потому как оно этот тип не имеет, а имеет (forall x. [x] -> Int)
Я предположил, что раз уж в качестве примера ты даешь пример с length, то, все-таки, функция применима не к любому типу, и дал подходящее под этот вариант определение, с функтором

yroslavasako

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

alfadred

В том и проблема, что с точки зрения логики всё нормально. Если заменить функцию макросом, то она будет корректна при подстановке в любом случае. Она должна принимать либо два одинаковых типа и функцию над ними, либо два члена одного класса и функцию класса. Вопрос в том, как с учётом ограниченности хаскеля это записать.
ИМХО, никак, если хочется макросов, то надо использовать что-нибудь больше на них похожее.
Мне кажется, тип "функции, применимые к двум заданным типам и возвращающие a" не выражается в той системе, что сейчас есть. Для конкретного класса C можно записать (Eq a, C b, C c) => (forall x. (C x) => x -> a) -> b -> c -> a, но я так понимаю, тебя это тоже не устраивает.
Пиши в списки рассылки, если хочешь, feature request в GHC отправь, но, боюсь, тебе скажут, что плохо реализуемо это. Хотя мб я чего-то очевидного не вижу. А пока используй то, что уже есть и подходит для ситуации.

yroslavasako

не выражается в той системе, что сейчас есть.
но оно вроде не противоречит выводимости.

Ivan8209

> Я же хочу функцию высшего порядка записать.
Судя по всему, ты хочешь не функцию высшего порядка,
а иную систему типов, где есть поддерживаются подтипы.
Объясни, почему тебя не устраивает вывод типа, он же выводится.
Я не спец в хаскелле, но он не должен был уйти настолько далеко от ML.
---
...Я работаю антинаучным аферистом...

karkar

Чего-то я не пойму, а куда вывод типа делся?
val testmean = fn : ('a -> ''b) -> 'a -> 'a -> bool

Проблема в том, что тут testmean требуют значения одного типа, а ТС хочет разного.

Ivan8209

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

yroslavasako

в хаскеле есть классы. И они органично вписываются в его концепцию

Ivan8209

Классы и типизация, в общем-то, независимы.
---
...Я работаю...

apl13

testMean :: Eq a => (x -> a) -> (y -> a) -> x -> y -> Bool 

не прокатит за воркараунд?

yroslavasako

не прокатит за воркараунд?
я уже давно забил на функции высшего порядка. Пишу не выёживаясь. Правда ожидал большего.

apl13

Строгая типизация очень строгая, видишь ли.

Ivan8209

Я всё же думаю, что дело не в строгости типизации.
Вообще, не использовать функции высшего порядка просто глупо.
---
"I don't know why nobody told you
How to unfold..."
Оставить комментарий
Имя или ник:
Комментарий: