4

I am trying to import the following JavaScript function into PureScript using the FFI:

function getGreeting() {
  return "Hi, welcome to the show."
}

but I am not sure what the type should be. The closest I get to is something like:

foreign import getGreeting :: Unit -> String

I do want getGreeting to stay a function, and not convert it to a constant.

Is there a better way to write the type? I tried to see what PureScript does if I define a dummy function in PureScript itself with that type of signature:

var getGreeting = function (v) {
  return "Hi, welcome to the show.";
};

Is there a way to get rid of that v parameter that is not being used?

TIA

Rouan van Dalen
  • 748
  • 4
  • 14
  • 1
    "I do want getGreeting to stay a function, and not convert it to a constant" I think that this function is a constant. Why you want to have such a function? – paluh Jul 19 '17 at 10:07
  • If you are using some kind of side effect or you are relying on some external state to produce or fetch this value, I think that you can set this function type to `getGreeting :: forall eff. Eff (SOME_EFFECT | eff) String` . – paluh Jul 19 '17 at 10:18
  • @paluh I do not want to change `getGreeting` because it is not my source code and should be considered unchangeable for now :) Also there are no side effects, so having the `Eff` type is undesirable. – Rouan van Dalen Jul 19 '17 at 11:59

2 Answers2

3

There is really useful packagepurescript-functions which can be helpful in such a situation and if you really have to call this function from Purescript as it is (because I think that it IS really just a constant) you can try:

module Main where

import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Data.Function.Uncurried (Fn0, runFn0)

foreign import getString ∷ Fn0 String

main :: forall e. Eff (console :: CONSOLE | e) Unit
main = do
  log (runFn0 getString)

I've created this simple javascript module so this example can be tested:

/* global exports */
"use strict";

// module Main

exports.getString = function() {
  return "my constant string ;-)";
};
paluh
  • 2,171
  • 20
  • 14
  • thanks paluh. It is good to know about `Data.Function.Uncurried`. I decided to go with the answer from gb because for something so simple, giving the type `Unit -> String` seems like the simplest solution. – Rouan van Dalen Jul 20 '17 at 05:55
  • Cool! `Data.Function.Uncurried` can be especially useful when you have functions WITH (multiple) arguments on the javascript side and don't want to wrap them to write FFI bindings ;-) – paluh Jul 20 '17 at 08:02
3

Unit -> String is a perfectly good type for that, or perhaps forall a. a -> String. The latter type may seem too permissive, but we know for sure that the a is unused thanks to parametricity, so that the function still must be constant.

gb.
  • 4,629
  • 1
  • 20
  • 19