Skip to content

Instantly share code, notes, and snippets.

@Swordlash
Created January 14, 2023 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Swordlash/ed73461cf2f1e1206e9220d093647a83 to your computer and use it in GitHub Desktop.
Save Swordlash/ed73461cf2f1e1206e9220d093647a83 to your computer and use it in GitHub Desktop.
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Foreign.C.String
import Foreign.Ptr
import Control.Monad (forM_)
import Text.Blaze.Html5 as H
import Text.Blaze.Html5.Attributes as A
import Text.Blaze.Html.Renderer.Pretty
import Data.IORef
foreign import javascript "((html) => document.documentElement.innerHTML = h$decodeUtf8z(html,0))"
setInnerHtml :: CString -> IO ()
foreign import javascript "((txt) => console.log(h$decodeUtf8z(txt,0)))"
logConsole :: CString -> IO ()
foreign import javascript "((fun) => document.body.onclick = (() => fun()))"
setBodyOnClick :: FunPtr (IO ()) -> IO ()
foreign import ccall "wrapper" createFunPtr :: (IO ()) -> IO (FunPtr (IO ()))
numbers :: Int -> Html
numbers n = docTypeHtml $ do
H.head $ do
H.title "Natural numbers"
body $ do
p "A list of natural numbers:"
ul $ forM_ [1 .. n] (li . toHtml)
main :: IO ()
main = do
withCString "Hello, JS!" logConsole
ref <- newIORef 1
withCString (renderHtml $ numbers 1) setInnerHtml
callback <- createFunPtr $ do
val <- atomicModifyIORef' ref (\v -> (v+1, v+1))
withCString (show val) logConsole
withCString (renderHtml $ numbers val) setInnerHtml
setBodyOnClick callback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment