2016-12-01 1 views
1

Отличная PureScript book объясняет, чтоПочему не Eff есть стрелка последнего возвращаемого значения

fullName :: forall r. Record (firstName :: String, lastName :: String | r) -> String 
fullName person = person.firstName <> " " <> person.lastName 

, а затем сравнивает Eff монада

import Prelude 

import Control.Monad.Eff.Random (random) 
import Control.Monad.Eff.Console (logShow) 

main :: forall eff. Eff (console :: CONSOLE, random :: RANDOM | eff) Unit 
main = do 
    n <- random 
    logShow n 

Мой вопрос: Почему не в подписи main содержится -> до единицы, т.е.

main :: forall eff. Eff (console :: CONSOLE, random :: RANDOM | eff) -> Unit 

Это сделало бы его похожим на -> String как в подписи fullName

отрывок из той же главы (курсив мой):

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

.

+0

Вы понимаете, что это означает, что вид [ 'Eff'] (https://pursuit.purescript.org/packages/purescript-eff/2.0.0/docs /Control.Monad.Eff#t:Eff) является '#! -> * -> * '? –

+0

Немного. Я перечитал это, и это действительно помогает понять мое понимание. благодаря – RAbraham

ответ

1

Одно из отличий между обеими функциями заключается в том, что fullName имеет параметр (до ->). Подпись функции утверждает, что она берет некоторую запись и возвращает строку.

main не принимает никаких параметров, так как это «точка входа» для приложения, и он возвращает Eff. Так main всего лишь возвращает один type. У этого типа есть два типа .

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

В настоящее время Eff - это тип, который сочетает в себе некоторые эффекты и некоторый «фактический результат». Его конструктор применяется с эффектной строкой в ​​качестве первого параметра, а результат - вторым параметром. В случае main все, что он делает, это побочные эффекты, поэтому «фактический результат» равен Unit, что в принципе ничего.

Если подпись main был:

main :: forall eff. Eff (console :: CONSOLE, random :: RANDOM | eff) -> Unit 

, что означало бы, что

  • Eff только принимает некоторый эффект строку в качестве параметра типа (не соответствует определению Eff)
  • main принимает параметр Eff в качестве параметра (но были ли они получены?)
  • main возвращает только Unit
Смежные вопросы