2015-11-17 3 views
6

Интересно, если это возможно, чтобы иметь функцию (несколько похожий на dataToTag#), как:Есть ли способ определить во время выполнения, в GHC, является ли абстрактное значение функцией?

isFunction# :: a -> Bool 

или, вероятно, что то же самое:

isFunction# :: Any -> Bool 

который возвращает True тогда и только тогда значения, переданного в качестве аргумента из a тип a -> b (или, если на то пошло, a => b) во время выполнения для некоторых типов a и b, или newtype, базовый тип которого (поэтому он «видит» через newtype s, b ut, конечно, не data), не форсируя его аргумент. Я не видел ничего подобного в GHC.Prim сам, но я, возможно, что-то пропустил, или, возможно, это возможно с помощью ручного CMM-примока или что-то в этом роде.

Теперь, когда вопрос мне пришло в голову мне любопытно об ответе за свое имя (question Y), но первопричиной мне пришло в голову (вопрос X) является то, что жалоба обычно выдвигаемые против seq является то, что ему нарушает эту эквивалентность, позволяя наблюдать разницу между undefined и \_ -> undefined, и мне было интересно, можно ли сделать версию seq (myseq a = if isFunction# a then flip const a else seq a), которая по-прежнему «магически полиморфна» (работает forall a), но просто оставляет функции в одиночку ,

+1

Как 'a => b' тип функции? –

+2

@ReinHenrichs: это на самом деле. '=>' desugared to '->' в GHC Core. –

+0

@ReinHenrichs (Передача слова A.K.A.) – glaebhoerl

ответ

4

Нет, конечно нет. Как он мог знать, не оценивая аргумент?

Но для того, чтобы ответить на ваш вопрос X напрямую, ваш предложенный myseq хуже, чем реальный seq, так как он нарушает параметричность. Есть myseq undefined :: b -> b дно или личность? Это зависит от того, была ли задана переменная типа a (undefined :: a) с типом функции.

В Haskell вы всегда могут опустить forall a. когда a не появляется в типе вообще, благодаря parametricity: выбор a не имеет значения. Ваш myseq потеряет это свойство.

Вот почему вы не смогли реализовать isFunction# без аннотирования значений во время выполнения с их предполагаемыми типами (isFunction# undefined также не имеет смысла).

+0

'seq' сам ломает параметричность. – dfeuer

+0

Ну, слова нечеткие. Он не нарушает ту же функцию, что и 'myseq'. –

+1

Более конкретно, я думаю, что это согласуется с идеей параметричности, что все типы, которые вы можете количественно оценить, поддерживают некоторые общие операции. Тогда вы получите соответственно более слабые гарантии от параметричности. Но если вы можете написать выражения типа 'forall a. Int', значение которого зависит от выбора типа 'a', то у вас вообще нет никакой формы параметричности. –

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