PureScript - AFF require(...).main 不是函数
PureScript - AFF require(...).main is not a function
考虑以下代码示例,直接取自手册中关于异步效果的章节。
-- https://book.purescript.org/chapter9.html
module Main where
import Prelude
import Data.Either (Either(..))
import Effect.Aff (Aff, attempt, message)
import Effect.Class.Console (log)
import Node.Encoding (Encoding(..))
import Node.FS.Aff (readTextFile, writeTextFile)
import Node.Path (FilePath)
copyFile :: FilePath -> FilePath -> Aff Unit
copyFile file1 file2 = do
my_data <- readTextFile UTF8 file1
writeTextFile UTF8 file2 my_data
main :: Aff Unit
main = do
result <- attempt $ copyFile "file1.txt" "file2.txt"
case result of
Left e -> log $ "There was a problem with copyFile: " <> message e
_ -> pure unit
但是,当此应用程序 运行 与 Spago 运行 一起使用时,它会产生以下令人费解的错误,这似乎类似于 JavaScript 错误而不是 PureScript 错误。
require(...).main is not a function
问题如下:
- 必须以何种方式更改此代码才能产生所需的效果(文件的复制)
- 导致上述错误的原因是什么疏忽或配置错误?
简短回答:main
必须是 Effect
,而不是 Aff
。
你的main
是一个Aff
,错误信息是绝对正确的:Aff
确实不是一个函数。它是一个代表异步计算的 non-trivial 数据结构,它不能从 JavaScript 简单地“启动”而不涉及太多 PureScript 内部结构。
另一方面,Effect
在 JavaScript 端被建模为无参数函数。例如,像这样:
f :: Effect Int
f = pure 42
像这样编译为 JavaScript:
const f = () => 42
通过示例对这一事实进行了更长的讨论。
所以,如果你给你的 main
类型 Effect Unit
,就可以从 JavaScript 像这样简单地调用它:
require("output/Main/index.js").main()
只是调用一个没有参数的函数。这正是运行时试图做的。
但是如果您需要在 main
中执行异步操作怎么办?
您可以通过 launchAff_
启动 Aff
异步计算,它本身具有类型 Effect Unit
,但将 Aff
计算作为参数并异步启动它:
main :: Effect Unit
main = launchAff_ do
result <- attempt $ copyFile "file1.txt" "file2.txt"
case result of
Left e -> log $ "There was a problem with copyFile: " <> message e
_ -> pure unit
这样,main
函数本身将调用 launchAff_
并立即终止,但启动的 Aff
计算将继续,程序不会退出,直到最后一个 Aff
计算停止。
考虑以下代码示例,直接取自手册中关于异步效果的章节。
-- https://book.purescript.org/chapter9.html
module Main where
import Prelude
import Data.Either (Either(..))
import Effect.Aff (Aff, attempt, message)
import Effect.Class.Console (log)
import Node.Encoding (Encoding(..))
import Node.FS.Aff (readTextFile, writeTextFile)
import Node.Path (FilePath)
copyFile :: FilePath -> FilePath -> Aff Unit
copyFile file1 file2 = do
my_data <- readTextFile UTF8 file1
writeTextFile UTF8 file2 my_data
main :: Aff Unit
main = do
result <- attempt $ copyFile "file1.txt" "file2.txt"
case result of
Left e -> log $ "There was a problem with copyFile: " <> message e
_ -> pure unit
但是,当此应用程序 运行 与 Spago 运行 一起使用时,它会产生以下令人费解的错误,这似乎类似于 JavaScript 错误而不是 PureScript 错误。
require(...).main is not a function
问题如下:
- 必须以何种方式更改此代码才能产生所需的效果(文件的复制)
- 导致上述错误的原因是什么疏忽或配置错误?
简短回答:main
必须是 Effect
,而不是 Aff
。
你的main
是一个Aff
,错误信息是绝对正确的:Aff
确实不是一个函数。它是一个代表异步计算的 non-trivial 数据结构,它不能从 JavaScript 简单地“启动”而不涉及太多 PureScript 内部结构。
Effect
在 JavaScript 端被建模为无参数函数。例如,像这样:
f :: Effect Int
f = pure 42
像这样编译为 JavaScript:
const f = () => 42
所以,如果你给你的 main
类型 Effect Unit
,就可以从 JavaScript 像这样简单地调用它:
require("output/Main/index.js").main()
只是调用一个没有参数的函数。这正是运行时试图做的。
但是如果您需要在 main
中执行异步操作怎么办?
您可以通过 launchAff_
启动 Aff
异步计算,它本身具有类型 Effect Unit
,但将 Aff
计算作为参数并异步启动它:
main :: Effect Unit
main = launchAff_ do
result <- attempt $ copyFile "file1.txt" "file2.txt"
case result of
Left e -> log $ "There was a problem with copyFile: " <> message e
_ -> pure unit
这样,main
函数本身将调用 launchAff_
并立即终止,但启动的 Aff
计算将继续,程序不会退出,直到最后一个 Aff
计算停止。