为什么 Eff 没有最后一个 return 值的箭头

Why doesn't Eff have an arrow for the last return value

优秀的PureScript book解释说

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

然后比较 Eff monad

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 的签名在 Unit 之前不包含 ->

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

这将使它类似于 -> String 的签名,如 fullName

的签名

同一章节的摘录(强调我的):

main is a computation with side-effects, which can be run in any environment which supports random number generation and console IO, and any other types of side effect, and which returns a value of type Unit

.

两个函数之间的一个区别是 fullName 有一个参数(在 -> 之前)。函数签名表明它需要一些记录和 returns 一个字符串。

main不带任何参数,因为它是"entry point"一个应用,returnsEff。所以 main 只是 returns 一个 类型。该类型恰好有两个 类型参数 .

函数参数和类型参数看起来很像,但它们是不同层次的。采用参数的类型有一个构造函数,并应用它们的参数来生成实际类型。它看起来像函数应用程序,但在类型级别! "signature" 的类型叫做 kind... 你可以了解更多,但是把它想象成 "types of types".

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

如果 main 的签名是:

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

这意味着

  • Eff只取部分效果行作为类型参数(不符合Eff的定义)
  • mainEff 作为参数(但它会来自哪里?)
  • main returns 只是 Unit