2

I would like to pass the string "Hello World" to the following Haskell script:

main :: IO ()
main = interact id

that sits inside a Heredoc. Is that possible ?

I have made a minimal reproducible example (does not currently work):

#!/bin/bash
echo "Hello World" | runhaskell <<HASKELL_END 2>/dev/null
main :: IO ()
main = interact id
F. Zer
  • 1,081
  • 7
  • 9

1 Answers1

2

You can do it if it's okay for you to use zsh.

#!/bin/zsh
echo "Hello World" | runghc =(cat <<'HASKELL_END'
main :: IO ()
main = interact id
HASKELL_END
)

or

#!/bin/zsh
echo "Hello World" | runghc =(<<<'
main :: IO ()
main = interact id'
)

The thing is, you need to pass your source code as a file since interact closes stdin. Unfortunately, process substitution in bash doesn't work well since ghc tries to get a size of the named pipe.

So this doesn't work.

#!/bin/bash
echo "Hello World" | runghc <(cat <<HASKELL_END
main :: IO ()
main = interact id
HASKELL_END
)

It gives this error.

*** Exception: /dev/fd/63: hFileSize: inappropriate type (not a regular file)

Of course, you can create a temporary file and delete it manually just like (= ) does internally.

snak
  • 6,483
  • 3
  • 23
  • 33
  • Thank you for your excellent answer. Could you tell me where is `(= )` documented ? – F. Zer Mar 23 '23 at 14:04
  • 1
    You can find it here. https://zsh.sourceforge.io/Doc/Release/Expansion.html#Process-Substitution – snak Mar 23 '23 at 23:18