2016-12-01 88 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

从同一章节(重点煤矿)的摘录的签名:

主要是有副作用的计算,它可以运行在支持随机数生成和控制台IO, 和任何其它类型的副作用任何 环境,并且其返回类型的值 单位

+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只是返回一个类型。该类型恰好有两个类型参数

函数参数和类型参数看起来完全相同,但它们处于不同的级别。带参数的类型具有构造函数,并应用其参数来生成实际类型。它看起来像函数应用程序,但在类型级别!类型的“签名”被称为 ...您可以了解更多关于它的内容,但可以将其视为“类型的类型”。

现在Eff是一种结合了一些效果和一些“实际结果”的类型。其构造函数应用效果行作为第一个参数,结果类型作为第二个参数。在main的情况下,它所做的只是副作用,所以“实际结果”是Unit,这基本上什么都没有。

如果main的签名是:

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

这将意味着

  • Eff只需要一定的效果行作为类型参数(不匹配的Eff定义)
  • mainEff作为参数(但它是从哪里来的?)
  • main回报只是Unit