Purescript

93 readers
2 users here now

founded 2 years ago
MODERATORS
1
12
UUID in Purescript (self.purescript)
submitted 4 months ago* (last edited 4 months ago) by demesisx to c/purescript
 
 

I ran into a situation the other day where UUID was needed. Sadly, the UUID module in pursuit depends on an npm package. So, I rolled my own.

I’d be happy to hear of any holes in my implementation and any other critiques anyone has to offer.

Here’s the code:

module UUID where

import Prelude
import Data.Either (Either(..))
import Data.Int.Bits ((.|.))
import Data.Maybe (Maybe(..))
import Data.String (joinWith, length)
import Data.String.Regex (regex, test)
import Data.String.Regex.Flags (noFlags)
import Effect (Effect)
import Data.Int (floor, hexadecimal, toNumber, toStringAs)
import Effect.Random (random)
import Data.Array (replicate)

newtype UUID = UUID String

instance showUUID :: Show UUID where
  show (UUID uuid) = uuid
derive instance eqUUID :: Eq UUID
derive instance ordUUID :: Ord UUID

randomInt :: Int -> Int -> Effect Int
randomInt min max = do
  r <- random
  pure $ floor $ r * toNumber (max - min + 1) + toNumber min

padStart :: Int -> String -> String
padStart targetLength str =
  let
    paddingLength = max 0 (targetLength - length str) 
    padding = replicate paddingLength "0" 
  in joinWith "" padding <> str


parseUUID :: String -> Maybe UUID
parseUUID str = 
  case regex "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" noFlags of
    Left _ -> Nothing
    Right r -> if test r str
               then Just $ UUID str
               else Nothing

uuidToString :: UUID -> String
uuidToString (UUID uuid) = uuid

emptyUUID :: UUID
emptyUUID = UUID "00000000-0000-0000-0000-000000000000"

-- | Generate a UUID v4
genUUID :: Effect UUID
genUUID = do
  -- Generate random 16-bit integers for smaller chunks
  r1 <- randomInt 0 0xFFFF  -- First half of time_low
  r2 <- randomInt 0 0xFFFF  -- Second half of time_low
  r3 <- randomInt 0 0xFFFF  -- time_mid
  r4 <- randomInt 0 0x0FFF  -- time_hi (12 bits for randomness)
  r5 <- randomInt 0 0x3FFF  -- clock_seq (14 bits for randomness)
  r6 <- randomInt 0 0xFFFF  -- First part of node
  r7 <- randomInt 0 0xFFFF  -- Second part of node
  r8 <- randomInt 0 0xFFFF  -- Third part of node

  -- Set the version (4) and variant (10)
  let versioned = r4 .|. 0x4000  -- Set version to 4 (binary OR with 0100 0000 0000 0000)
      variant = r5 .|. 0x8000    -- Set variant to 10xx (binary OR with 1000 0000 0000 0000)

  -- Convert to hex and pad as needed
  let hex1 = padStart 4 (toHex r1) <> padStart 4 (toHex r2)  -- time_low
      hex2 = padStart 4 (toHex r3)                           -- time_mid
      hex3 = padStart 4 (toHex versioned)                    -- time_hi_and_version
      hex4 = padStart 4 (toHex variant)                      -- clock_seq
      hex5 = padStart 4 (toHex r6) <> padStart 4 (toHex r7) <> padStart 4 (toHex r8) -- node
      uuid = joinWith "-" [hex1, hex2, hex3, hex4, hex5]

  pure $ UUID uuid
  where
    toHex = toStringAs hexadecimal
2
 
 

#fp #functionalprogramming #purescript #scala

3
 
 

This presentation was recorded at YOW! 2016. #GOTOcon #YOW https://yowcon.com

Rob Howard - Software Engineer at Ambiata ‪@damncabbage‬

RESOURCES https://x.com/damncabbage https://chaos.social/@buzzyrobin https://github.com/damncabbage / buzzyrobin
https://rhoward.id.au

Links http://robhoward.id.au/talks/2016/04/... https://github.com/damncabbage/ylj16-... https://github.com/damncabbage/puresc... https://www.purescript.org

ABSTRACT This talk and workshop/jam will introduce you to PureScript, a strongly-typed, Haskell-inspired programming language that compiles to JavaScript. These sessions will focus on building a small game in incremental steps, from simple functions to a web-based app, giving you a chance to try out features and libraries along the way. You should leave the session with a grasp of PureScript fundamentals, and a self-sufficiency to tackle your own projects and experiments.

RECOMMENDED BOOKS Phil Freeman • PureScript by Example • https://leanpub.com/purescript Christopher Allen & Julie Moronuki • Haskell Programming • https://lorepub.com/product/haskellbook Edsger W. Dijkstra • A Discipline of Programming • https://amzn.to/3JlwHV6 Rebecca Skinner • Effective Haskell • https://amzn.to/3SxTpwY Uberto Barbini • From Objects to Functions • https://amzn.to/4cMDOmH

4
 
 

cross-posted from: https://lemmy.world/post/20776659

A quick, naive AI generated Purescript translation (quickly generated that probably doesn’t work but will help get me started later)


module Main where

import Prelude
import Effect (Effect)
import Effect.Aff (launchAff_)
import Effect.Aff.Timer (setInterval)
import Effect.DOM (window)
import Web.HTML (document)
import Web.HTML.Document (getElementById)
import Web.HTML.Element (Element, toElement)
import Web.HTML.HTMLCanvasElement (getContext2D, getCanvasElementById)
import Web.HTML.Canvas.Image (newImage, getWidth, getHeight, setSrc)
import Web.HTML.Canvas.CanvasRenderingContext2D (CanvasRenderingContext2D, drawImage)
import Web.HTML.Types (CanvasElement, Image)
import Web.DOM.Node.Types (Node)

foreign import requestAnimationFrame :: (Effect Unit -> Effect Unit) -> Effect Unit

-- Loads the image and begins the animation
startAnimation :: Effect Unit
startAnimation = do
  img <- newImage
  setSrc img "example1.jpg"
  canvas <- getCanvasElementById "myCanvas"
  context <- getContext2D canvas

  -- We defer animation start until the image is loaded
  imgOnLoad img (beginAnimation context img)

-- Sets the image `onload` handler, safely deferring canvas drawing until the image is ready
imgOnLoad :: Image -> Effect Unit -> Effect Unit
imgOnLoad img action = do
  foreignOnload img action

foreign import foreignOnload :: Image -> Effect Unit -> Effect Unit

-- Initializes the animation loop
beginAnimation :: CanvasRenderingContext2D -> Image -> Effect Unit
beginAnimation context img = do
  imageWidth <- getWidth img
  imageHeight <- getHeight img
  let row = imageHeight
  requestAnimationFrame (animate context img row imageWidth imageHeight)

-- Animates drawing row by row
animate :: CanvasRenderingContext2D -> Image -> Int -> Int -> Int -> Effect Unit
animate context img row imageWidth imageHeight = do
  drawImage context img 0 row imageWidth 1 0 0 imageWidth row
  let nextRow = if row > 0 then row - 1 else imageHeight
  requestAnimationFrame (animate context img nextRow imageWidth imageHeight)

main :: Effect Unit
main = do
  startAnimation

5
 
 

This video demonstrates a quick way to have something nice running with purescript (react + tailwind css + shadcn/ui components)

Repository: https://github.com/Zelenya/purescript-shadcn-tailwind-copypaste

Check out my course "How to think like a functio programmer": https://impurepics.thi.

#fp #functionalprogramming #purescript

6
 
 

I've seen a bit of chatter recently in the PS community about dependent types. Many of us that have been using PureScript for years love it because of its simplicity and elegance, and there has been resistance in the community to build out the complexity, both syntax-wise and implementation-wise, of a full-blown dependently-typed language à la Idris and Agda.

But another reason that there's not much community momentum behind adding dependent types to PureScript is because PureScript already has dependent types 😁

7
8
 
 

For whatever reason, I decided at 27:00 Friday that I should make a program that would get audio from videos of a Youtube channel. This article will go over the details on why and how I made this with Purescript (and some FFI).

9
 
 

Teaser for the benefits of strongly typed pure functional programming

10
11