You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PureScript FFI与Aff Monad问题:为何定义的effect从未执行?

Hey there! Let's walk through some common fixes for this Aff Monad FFI issue you're hitting—super common when you're starting out with PureScript, so don't sweat it.

1. Double-check your FFI implementation properly constructs an Aff instance

Aff isn't just a regular async function—it relies on notifying the PureScript runtime when it's done. A common mistake is forgetting to trigger the success (or failure) callback that makeAff expects.

For example, if your FFI code looks like this (wrong):

exports.delayedLog = function() {
  setTimeout(() => console.log("keyMessage"), 1000);
};

This won't work because it never tells the Aff runtime that the async operation completed. Instead, your FFI needs to return a function that accepts success and failure callbacks, and invokes success once the work is done:

exports.delayedLog = function() {
  return function(success, failure) {
    setTimeout(function() {
      console.log("keyMessage");
      success(); // Critical: Signal the Aff computation is finished
    }, 1000);
    // Return a cleanup function (empty here since we don't need to cancel the timeout)
    return function() {};
  };
};

2. Make sure you're actually running the Aff computation

Aff is lazy—defining an Aff value doesn't execute it automatically. You need to explicitly launch it using functions like launchAff_ (for fire-and-forget) or runAff (if you need to handle the result/errors).

If your Main.purs only has something like:

foreign import delayedLog :: Aff Unit

main = delayedLog -- Wrong! This doesn't run the Aff

That's why your program hangs. Instead, convert it to an Effect and run it:

module Main where

import Effect (Effect)
import Effect.Aff (Aff, launchAff_)
import Effect.Console (log)

foreign import delayedLog :: Aff Unit

main :: Effect Unit
main = launchAff_ delayedLog -- Correct: Launches the Aff computation

3. Verify your PureScript type signature matches the FFI

Ensure your foreign import has the correct type—if you accidentally wrote Effect Unit instead of Aff Unit, the runtime will misbehave. Double-check that your import line looks like:

foreign import delayedLog :: Aff Unit

4. Check for unhandled errors in the FFI

If your timeout logic throws an error (even a silent one) and you don't call the failure callback, the Aff computation will hang indefinitely. Add a try-catch in your FFI to handle this:

exports.delayedLog = function() {
  return function(success, failure) {
    setTimeout(function() {
      try {
        console.log("keyMessage");
        success();
      } catch (err) {
        failure(err); // Pass errors to the Aff runtime
      }
    }, 1000);
    return function() {};
  };
};

You can also add error handling in PureScript with catchError to see if any errors are being swallowed:

main = launchAff_ $ delayedLog `catchError` \err -> log $ "Error: " <> show err

Give these steps a shot—chances are one of these is the culprit!

内容的提问来源于stack exchange,提问作者Nick Saunders

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:15:28