2015-12-15 3 views
22

Является ли Haskell строго типизированным? То есть можно ли изменить тип переменной после того, как вы ее назначили? Кажется, я не могу найти ответ в Интернете.Является ли Haskell строго типизированным языком программирования?

+8

Является ли Haskell строго типизированным, зависит от того, нравится ли вам его система типа или нет. См. Http://ericlippert.com/2012/10/15/is-ca-strongly-typed-or-a-weakly-typed-language/ –

+7

[«Сильно типизированные» и «слабо типизированные» плохо определены. ] (http://programmers.stackexchange.com/a/38257/102349) Вероятно, вы хотите спросить, динамически ли Haskell набирается (нет, это не так). –

+10

Обратите внимание, что в Haskell вы не можете даже изменить * значение * переменной после ее назначения; поэтому, даже если Haskell был динамически введен, тип переменной времени выполнения будет фиксирован при назначении. – ruakh

ответ

75

Статические - типы известны во время компиляции. Java и Haskell статически типизированы.

Статически типизированный язык может иметь или не иметь тип вывода. Java почти полностью не имеет вывода типа (но он очень медленно меняется немного); Haskell имеет полный вывод типа (за исключением некоторых очень продвинутых расширений).

Динамический - Python, Ruby и т. Д. Некоторые люди называют это «унифицированным»; динамический может быть «эмулирован» в статической настройке, но обратное неверно, если вы не добавите внешние инструменты/плагины для статического анализа на иначе динамически типизированный язык. Некоторые языки смешиваются динамически и статично.

Strong - значения, которые должны быть обработаны как Cat; пытаясь обработать их, как Dog вызовет громкий meeewww ... Я имею в виду ошибку.

Слабый - это эффективно сводится к 2 похожих, но разных вещей: тип принуждения (например "5"+3 равен в PHP 8 - или делает это!) И переосмысление памяти (например,(int) someCharValue или (bool) somePtr в C и C++, но C++ хочет, чтобы вы прямо сказали reinterpret_cast). Так что действительно есть принуждение-слабый и reinterpretation-weak, а разные языки слабы в одном или обоих из этих способов.

Интересно отметить, что принуждение является неявным по своей природе, а переинтерпретация памяти является явной (за исключением Ассамблеи) - поэтому слабая типизация состоит из неявных и явного поведения. Возможно, это еще более повод ссылаться на 2 отдельные подкатегории при слабом наборе текста.


Есть языки со всеми 4 возможными комбинациями и вариациями/градациями.

Haskell статический + сильный; конечно, он имеет unsafeCoerce, поэтому он может быть статическим + немного переинтерпретировать-слабым время от времени, но unsafeCoerce очень сильно осуждается, за исключением чрезвычайных ситуаций, когда вы уверены в чем-то, но это просто не может убедить компилятор без все возвращается и пересказывает всю историю по-другому.

C статический + слабый, потому что вся память может свободно интерпретироваться как нечто, изначально не предназначенное для содержания, следовательно, слабое. Но все эти переосмысления отслеживаются с помощью проверки типа, поэтому все еще полностью статичны. Но C не делает неявных принуждений, так что это только reinterpret-weak.

Python является динамическим + почти полностью сильным - нет известных в любой строке коды до достижения этой строки во время выполнения типов, однако значений, которые живут во время выполнения действительно есть типы, связанные с ними, и это невозможно переосмысливать Память. Неявные принуждения также сохраняются до значимого минимума, поэтому можно сказать, что Python на 99,9% сильный и 0,01% принуждение-слабый.

PHP и JavaScript является динамическими + в основном слабыми - динамичные, в том, что ничто не имеет типа, пока вы не выполните и самоанализ его содержания, а также слабые в том, что принуждение происходят все время и с вещами, вы действительно никогда не ожидать быть принужденными, если только вы не вызываете только методы и функции, а не используете встроенные операции. Эти принуждения являются источником большого количества юмора в Интернете. Нет никаких реинтерпретаций памяти, поэтому PHP и JS равны coercion-weak.


Кроме того, некоторые люди хотели бы думать, что статическая типизация о переменных, имеющих тип, и строгая типизация о значениях, имеющих тип - это очень полезный способ идти о понимании полной картины, но это не совершенно верно: некоторые динамически типизированные языки также позволяют аннотировать переменные/параметры с типами/ограничениями, которые применяются во время выполнения.

В статической типизации это выражения, которые имеют тип; факт переменных, имеющих тип, является следствием того, что переменные используются как средство для склеивания больших выражений вместе с меньшими, поэтому это не переменные как таковые, которые имеют типы.

Аналогичным образом, при динамическом наборе данных переменные не имеют статически известного типа - это все выражения! Переменные, не имеющие типа, являются просто следствием выражений, которые они хранят в отсутствие типа.


Один заключительный иллюстрации

В динамической типизации, все кошки, собаки и даже слонов (на самом деле целых зоопарков!) Упаковывают в коробки одинакового размера.

В статическом наборе эти поля выглядят по-разному и имеют наклейки на них, говорящие, что внутри.

Некоторым людям это нравится, потому что они могут просто использовать единый форм-фактор коробки и не должны помещать какие-либо ярлыки в коробки - это только расположение коробок относительно друг друга, которые неявно (и, надеюсь) предоставляют тип здравомыслие.

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

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

С ярлыками и ясными правилами о том, как обращаться с ящиками различных этикеток, автоматизированными/механизированными логическими рассуждения могут быть использованы для составления выводов о том, что система логистики не будет делать или будет делать точно (статическая проверка, формальное доказательство или, по крайней мере, псевдоподтверждение, такое как QuickCheck). Некоторые аспекты логистики все еще нуждаются в проверке с помощью пробные пробеги, такие как ли логистическая команда даже получила право клиента. (интеграционное тестирование, приемочные испытания, проверки работоспособности конечных пользователей).


Кроме того, в случае слабых собак можно нарезать и снова собрать как кошки франкенштейна. Нравится им это или нет, и является ли результат уродливым или нет. (слабый набор)

Но если вы добавляете ярлыки к коробкам, все равно важно, чтобы кошки Франкенштейна были помещены в кошки. (Статический + слабая типизация)


В сильной типизации, в то время как вы можете поместить кошку в коробке собаки, но вы можете продолжать притворяться, что это собака, пока вы пытаетесь унизить его, кормить его только что-то собаки будут есть - если это произойдет, это будет кричать вслух, но до этого времени, если вы будете динамично печататься, он молча примет свое место (в статическом мире он откажется быть помещен в коробку для собак перед вами может сказать «котенок»).

+0

Я бы не сказал, что невозможно переосмыслить память, есть несколько проектов, которые реализуют ассемблеры в Python, заполняя массив numpy инструкциями, а затем указывая ctypes в ячейке памяти и называя это функцией, и на самом деле технически возможно обменять тип объекта, но оба этих примера попадают в глубокие, темные уголки Питона, о которых, вероятно, даже о смертных не должно знать даже смертные. – bheklilr

+0

Переменные имеют типы, кроме выражений. Определение функции в Haskell будет иметь параметры (переменные), которые не привязаны к выражениям, но которые, безусловно, имеют типы. В System F и его родственниках переменные (но не выражения) должны быть явно аннотированы типами. – dfeuer

+0

Аргументы функции - это имена выражений, которые будут «помещены в них» - вот что я имел в виду концептуально; Я не притворялся, что я теоретически верю в терминологии :) –

0

Я думаю, вы говорите о двух разных вещах.

Во-первых, языки haskell и языки с функциональным программированием (FP) не имеют понятия «переменная». Вместо этого они используют понятие «имя» и «значение», они просто «связывают» значение с именем. Как только значение привязано, вы не можете привязать другое значение к тому же имени, это ключевая особенность FP.

Сильная типизация - это еще одна тема. Да, haskell строго типизирован, и поэтому большинство языков FP. Сильная типизация дает FP возможность «вывода типа», которая позволяет устранить скрытые ошибки во время компиляции и уменьшить размер исходного кода.

Возможно, вы сравниваете haskell с python? Python также строго типизирован. Разница между haskell и python - «статическая типизация» и «динамическая типизация». Фактическое значение термина «Сильный тип» и «Слабый тип» неоднозначно и нечетко. Это еще одна длинная история ...

+0

А теперь я вижу разницу. Благодаря! –

+3

извините, но вы смешаете сильные и статические, а также ссылаетесь на «проверку типов», но вместо этого говорите «вывод типа»: _Strong typing дает FP возможность «вывода типа», которая является мощной для устранения скрытых ошибок во время компиляции и помочь уменьшить размер исходного кода. –

+3

Мы * делаем * имеют понятие переменной; мы просто используем это слово по-другому. Переменная в функциональном языке во многом похожа на * математическую * переменную. – dfeuer

7

Вы, кажется, смешиваете динамическую/статическую и слабую/сильную типизацию.

Динамическое или статическое типирование касается того, можно ли изменить тип переменной во время выполнения.

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

Haskell как статически, так и строго типизирован.

Однако в Haskell нет такой переменной, как переменная, поэтому говорить о динамической или статической типизации не имеет смысла, поскольку каждый идентификатор, назначенный со значением, не может быть изменен при выполнении.

EDIT: Но, как сказал goldenbull, эти типизирующие понятия четко не определены.

+1

Сильная типизация сама по себе не позволяет вам ничего предсказывать; это только убеждает, что кошек в конечном итоге не воспринимают как собак (думайте, как ужасно это будет для кошки ...). Только статическая комбинация с сильным обеспечивает это; но опять же даже статический + слабый дает много предсказаний. –