Consider the following working code example, that uses launchAff_
to copy a JSON file:
module Main where
import Prelude
import Effect (Effect)
import Effect.Aff (Aff, launchAff_)
import Node.Encoding (Encoding(..))
import Node.FS.Aff (readTextFile, writeTextFile)
import Node.Path (FilePath)
duplicateCustomerData :: FilePath -> FilePath -> Aff Unit
duplicateCustomerData filePath1 filePath2 = do
customer_data <- readTextFile UTF8 filePath1
writeTextFile UTF8 filePath2 customer_data
main :: Effect Unit
main = launchAff_ do
duplicateCustomerData "database/customer-1.json" "database/customer-2.json"
However, if the main function is changed to use launchAff
(without the underscore) like so
main :: Effect Unit
main = launchAff do
duplicateCustomerData "database/customer-1.json" "database/customer-2.json"
The following error is thrown:
Could not match type
Fiber Unit
with type
Unit
Thus,
fiber unit
?fiber unit
? Is it meant to be discarded? What does it represent?Fiber
represents a running async computation.
The difference between Fiber
and Aff
is the "running" part. Aff
is not an async computation that is running, but rather a way to start an async computation. It's not started until you bind it in a larger computation. And conversely, you can start the same Aff
multiple times.
Fiber
, on the other hand, is an async computation that has already been started, it's already in progress. You can kill it via killFiber
or you can wait for it to complete via joinFiber
, and some other things. See the docs.
And now that we know that (1) Aff
is a way to start an async computation, and (2) Fiber
is an already-running async computation, it should become obvious that a Fiber
would be the result of starting an Aff
. Which is exactly what you observe: launchAff
takes an Aff
and returns a Fiber
.
But sometimes (in my own experience - most times) we don't actually need the resulting Fiber
. There is nothing we're going to do with it. For those cases, there is a convenience shortcut - launchAff_
. It does the same thing as launchAff
, but throws away the resulting Fiber
. See it for yourself in the source code.
Adding an underscore at the end to mean "returns unit" is a common pattern. For example, there are for
and for_
, there are traverse
and traverse_
, there are runAff
and runAff_
.