exercism / purescript

Exercism exercises in PureScript.
https://exercism.org/tracks/purescript
MIT License
37 stars 32 forks source link

Building a training set of tags for purescript #275

Closed ErikSchierboom closed 1 year ago

ErikSchierboom commented 1 year ago

Hello lovely maintainers :wave:

We've recently added "tags" to student's solutions. These express the constructs, paradigms and techniques that a solution uses. We are going to be using these tags for lots of things including filtering, pointing a student to alternative approaches, and much more.

In order to do this, we've built out a full AST-based tagger in C#, which has allowed us to do things like detect recursion or bit shifting. We've set things up so other tracks can do the same for their languages, but its a lot of work, and we've determined that actually it may be unnecessary. Instead we think that we can use machine learning to achieve tagging with good enough results. We've fine-tuned a model that can determine the correct tags for C# from the examples with a high success rate. It's also doing reasonably well in an untrained state for other languages. We think that with only a few examples per language, we can potentially get some quite good results, and that we can then refine things further as we go.

I released a new video on the Insiders page that talks through this in more detail.

We're going to be adding a fully-fledged UI in the coming weeks that allow maintainers and mentors to tag solutions and create training sets for the neural networks, but to start with, we're hoping you would be willing to manually tag 20 solutions for this track. In this post we'll add 20 comments, each with a student's solution, and the tags our model has generated. Your mission (should you choose to accept it) is to edit the tags on each issue, removing any incorrect ones, and add any that are missing. In order to build one model that performs well across languages, it's best if you stick as closely as possible to the C# tags as you can. Those are listed here. If you want to add extra tags, that's totally fine, but please don't arbitrarily reword existing tags, even if you don't like what Erik's chosen, as it'll just make it less likely that your language gets the correct tags assigned by the neural network.


To summarise - there are two paths forward for this issue:

  1. You're up for helping: Add a comment saying you're up for helping. Update the tags some time in the next few days. Add a comment when you're done. We'll then add them to our training set and move forward.
  2. You not up for helping: No problem! Just please add a comment letting us know :)

If you tell us you're not able/wanting to help or there's no comment added, we'll automatically crowd-source this in a week or so.

Finally, if you have questions or want to discuss things, it would be best done on the forum, so the knowledge can be shared across all maintainers in all tracks.

Thanks for your help! :blue_heart:


Note: Meta discussion on the forum

ErikSchierboom commented 1 year ago

Exercise: hello-world

Code

module HelloWorld where

import Prelude
import Data.Maybe (Maybe(..))

helloWorld :: Maybe String -> String
helloWorld Nothing = "Hello, World!"
helloWorld (Just name) = "Hello, " <> name <> "!"

Tags:

construct:string
construct:<>
construct:import
construct:module
construct:pattern-matching
construct:function
construct:parameter
construct:string
construct:variable
paradigm:functional
paradigm:metaprogramming
technique:concatenation
ErikSchierboom commented 1 year ago

Exercise: bob

Code

module Bob
  ( hey
  ) where

import Prelude
import Data.Either (fromRight)
import Data.List (findMap)
import Data.Maybe (isJust, fromMaybe, Maybe(..))
import Data.String (Pattern(..), length, stripSuffix, trim)
import Data.String.Regex (Regex, regex, test)
import Data.String.Regex.Flags (RegexFlags, noFlags)
import Partial.Unsafe (unsafePartial)

hey :: String -> String
hey s =
  fromMaybe "Whatever." $ findMap (\x -> x s) [isYelling, isQuestion, isSilent]

isQuestion :: String -> Maybe String
isQuestion s 
  | s # stripSuffix (Pattern "?") # isJust = Just "Sure."
  | otherwise                              = Nothing

isSilent :: String -> Maybe String
isSilent s
  | s # trim # length # (==) 0 = Just "Fine. Be that way!"
  | otherwise                  = Nothing

isYelling :: String -> Maybe String
isYelling s
  | test (getRegex "^(?=.*[A-Z]+)[^a-z]+[!?]?$" noFlags) s = Just "Whoa, chill out!"
  | otherwise = Nothing

getRegex :: String -> RegexFlags -> Regex
getRegex pattern flags =
  unsafePartial $ fromRight $ regex pattern flags

Tags:

No tags generated

ErikSchierboom commented 1 year ago

Exercise: pangram

Code

module Pangram (isPangram) where

import Prelude (map, ($))

import Data.String (toLower, toCharArray)
import Data.Char (fromCharCode)
import Data.Array ((..))
import Data.Set (difference, fromFoldable, isEmpty)

isPangram :: String -> Boolean
isPangram str =
  let
    alpha = fromFoldable $ map fromCharCode $ 97..122
    letters = fromFoldable $ toCharArray $ toLower str
  in
    isEmpty $ difference alpha letters

Tags:

construct:boolean
construct:char
construct:double
construct:expression
construct:implicit-conversion
construct:import
construct:infix-function
construct:int
construct:integral-number
construct:invocation
construct:let
construct:number
construct:parameter
construct:set
construct:string
construct:underscore
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
paradigm:reflective
technique:higher-order-functions
uses:Set
ErikSchierboom commented 1 year ago

Exercise: scrabble-score

Code

module ScrabbleScore (scoreWord) where

import Prelude ((#), (+), (/=), ($))
import Data.Array (foldl)
import Data.Maybe (Maybe(Nothing))
import Data.Tuple (Tuple(..), fst, snd)
import Data.String (Pattern(..), indexOf, singleton, toCharArray, toLower)

scoreWord :: String -> Int
scoreWord word =
  let
    wordChars = toLower word # toCharArray
  in
    foldl (\acc x -> acc + charToScore x) 0 wordChars

charToScore :: Char -> Int
charToScore char =
  let
    charsWithScore = [
      Tuple "aeioulnrst" 1,
      Tuple "dg" 2,
      Tuple "bcmp" 3,
      Tuple "fhvwy" 4,
      Tuple "k" 5,
      Tuple "jx" 8,
      Tuple "qz" 10
    ]
  in
    foldl (\acc x ->
      acc + if indexOf (Pattern $ singleton char) (fst x) /= Nothing
        then snd x else 0
    ) 0 charsWithScore

Tags:

construct:array
construct:char
construct:constructor-application
construct:function
construct:if-then-else
construct:implicit-conversion
construct:import
construct:int
construct:integral-number
construct:invocation
construct:lambda
construct:let
construct:list
construct:number
construct:parameter
construct:pattern-matching
construct:string
construct:tuple
construct:variable
paradigm:functional
technique:higher-order-functions
uses:Char
uses:List
uses:Tuple
ErikSchierboom commented 1 year ago

Exercise: scrabble-score

Code

module ScrabbleScore (scoreWord) where

import Prelude ((==), (>>>), (+), otherwise)
import Data.Foldable (foldr)
import Data.String (Pattern(..), split, toLower)
import Data.Record.Unsafe (unsafeGet, unsafeHas)

scoreMap = { a: 1
           , b: 3
           , c: 3
           , d: 2
           , e: 1
           , f: 4
           , g: 2
           , h: 4
           , i: 1
           , j: 8
           , k: 5
           , l: 1
           , m: 3
           , n: 1
           , o: 1
           , p: 3
           , q: 10
           , r: 1
           , s: 1
           , t: 1
           , u: 1
           , v: 4
           , w: 4
           , x: 8
           , y: 4
           , z: 10
           }

letterToScore :: String -> Int
letterToScore l
  | (unsafeHas l scoreMap) == true = unsafeGet l scoreMap
  | otherwise = 0

scoreWord :: String -> Int
scoreWord = (split (Pattern "")) >>> foldr (toLower >>> letterToScore >>> (+)) 0

Tags:

construct:boolean
construct:add
construct:assignment
construct:char
construct:comment
construct:field-initializer
construct:function
construct:import
construct:int
construct:integral-number
construct:invocation
construct:lambda
construct:method
construct:module
construct:number
construct:object
construct:parameter
construct:pattern-matching
construct:record
construct:string
construct:underscore
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions
uses:Pattern
ErikSchierboom commented 1 year ago

Exercise: triangle

Code

module Triangle
  ( Triangle(Equilateral, Isosceles, Scalene)
  , triangleKind
  ) where

import Data.Either (Either(..))
import Data.Array (any)
import Data.Tuple (Tuple(..), uncurry)
import Data.Generic (gShow, class Generic)
import Prelude

data Triangle = Equilateral | Isosceles | Scalene
derive instance eqT ∷ Eq Triangle
derive instance genericT ∷ Generic Triangle
instance showT ∷ Show Triangle where
    show = gShow

-- I don't like the usage of String as errors, so if it was me I would
-- define triangleKind to go to Either InvalidTriangleReason Triangle
-- Since that's not the case, how about another show instance? :)
data InvalidTriangleReason = NonPositiveLengths | InequalityViolated
instance showITR ∷ Show InvalidTriangleReason where
    show itr = case itr of
        NonPositiveLengths → "Invalid lengths"
        InequalityViolated → "Violates inequality"

triangleKind ∷ Int → Int → Int → Either String Triangle
triangleKind a b c
    | any (_ <= 0) [a, b, c] = Left $ show NonPositiveLengths
    | any (uncurry (\x y → x < y)) [Tuple (b+c) a, Tuple (a+c) b, Tuple (a+b) c] = Left $ show InequalityViolated
    | a == b && b == c           = Right Equilateral
    | a == b || b == c || a == c = Right Isosceles
    | otherwise                  = Right Scalene

Tags:

construct:add
construct:boolean
construct:case
construct:class
construct:comment
construct:data-declaration
construct:import
construct:instance
construct:int
construct:integral-number
construct:lambda
construct:list
construct:logical-and
construct:logical-or
construct:module
construct:number
construct:pattern-matching
construct:polymorphic-function
construct:string
construct:sum-type
construct:tuple
construct:underscore
construct:variable
paradigm:functional
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
uses:List
uses:Tuple
ErikSchierboom commented 1 year ago

Exercise: triangle

Code

module Triangle
  ( Triangle (Equilateral, Isosceles, Scalene)
  , triangleKind
  ) where

import Prelude

import Data.Array (sort)
import Data.Either (Either(..))
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Partial.Unsafe (unsafeCrashWith)

data Triangle = Equilateral | Isosceles | Scalene

derive instance eqTriangle :: Eq Triangle
derive instance genericTriangle :: Generic Triangle _
instance showTriangle :: Show Triangle where show = genericShow

triangleKind' :: Int → Int → Int → Either String Triangle
triangleKind' a b c
  | a < 1             = Left "Invalid lengths"
  | a + b <= c        = Left "Violates inequality"
  | a == b && b == c  = Right Equilateral
  | a == b || b == c  = Right Isosceles
  | otherwise         = Right Scalene

triangleKind :: Int → Int → Int → Either String Triangle
triangleKind a b c =
  case sort [a, b, c] of
    [a', b', c']  -> triangleKind' a' b' c'
    _             -> unsafeCrashWith "impossible"

Tags:

construct:add
construct:boolean
construct:case
construct:data-declaration
construct:import
construct:instance
construct:invisibility-modifier
construct:lambda
construct:list
construct:logical-and
construct:logical-or
construct:module
construct:parameter
construct:pattern-matching
construct:string
construct:underscore
construct:use
construct:visibility-modifiers
paradigm:functional
paradigm:logical
paradigm:object-oriented
technique:boolean-logic
ErikSchierboom commented 1 year ago

Exercise: matching-brackets

Code

module BracketPush (isPaired) where

import Prelude ((#), (==))

import Data.Map as M
import Data.Tuple (Tuple(..))
import Data.String (toCharArray)
import Data.Array (foldl, snoc, elemIndex, last, null, init)
import Data.Maybe (Maybe(Just), isJust, maybe, fromMaybe)

bracketsMap :: M.Map Char Char
bracketsMap = M.fromFoldable [
  Tuple '(' ')',
  Tuple '{' '}',
  Tuple '[' ']'
]

closingBrackets :: Array Char
closingBrackets = [')', '}', ']']

isPaired :: String -> Boolean
isPaired str =
  toCharArray str #
  foldl checkBrackets [] #
  null

checkBrackets :: Array Char -> Char -> Array Char
checkBrackets stack char =
  if M.member char bracketsMap then
    snoc stack char
  else if isJust (elemIndex char closingBrackets) then
    let lastBracket = last stack in
      maybe stack (
        \bracket ->
          if Just char == M.lookup bracket bracketsMap then
            fromMaybe [] (init stack)
          else
            snoc stack char
      ) lastBracket
  else
    stack

Tags:

construct:array
construct:char
construct:if-then-else
construct:implicit-conversion
construct:import
construct:invocation
construct:lambda
construct:let
construct:list
construct:method
construct:module
construct:null
construct:nullary
construct:parameter
construct:string
construct:then-expression
construct:tuple
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
uses:Map
ErikSchierboom commented 1 year ago

Exercise: allergies

Code

module Allergies
  ( allergicTo
  , list
  ) where

import Prelude

import Data.Array (filter, zip)
import Data.Int.Bits ((.&.))
import Data.Map (Map)
import Data.Map as Map
import Data.Maybe (Maybe(..))

allergens :: Array String
allergens = ["eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"]

powersOf2 :: Array Int
powersOf2 = [1, 2, 4, 8, 16, 32, 64, 128]

allergensMap :: Map String Int
allergensMap = Map.fromFoldable (zip allergens powersOf2)

allergicTo :: Int -> String -> Boolean
allergicTo n al = case Map.lookup al allergensMap of
  Just i -> n .&. i /= 0
  Nothing -> false

list :: Int -> Array String
list n = filter (allergicTo n) allergens

Tags:

construct:boolean
construct:case
construct:char
construct:double
construct:explicit-conversion
construct:expression
construct:field
construct:floating-point-number
construct:import
construct:infinite-precision-number
construct:int
construct:integral-number
construct:invocation
construct:lambda
construct:list
construct:module
construct:number
construct:parameter
construct:pattern-matching
construct:record
construct:string
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:bit-manipulation
technique:boolean
technique:higher-order-functions
technique:type-conversion
uses:Map
ErikSchierboom commented 1 year ago

Exercise: all-your-base

Code

module AllYourBase
  ( rebase
  ) where

import Data.Foldable (class Foldable)
import Data.List.Lazy (foldMap, foldl)
import Data.Maybe (Maybe(..))
import Data.Monoid.Conj (Conj(..))
import Data.Tuple (Tuple(..))
import Data.Unfoldable (class Unfoldable, unfoldr)
import Data.Array (null, head, all, reverse)
import Prelude (mod, not, otherwise, (#), ($), (&&), (*), (+), (/), (<), (<=), (==), (>=))

rebase :: Int -> Int -> Array Int -> Maybe (Array Int)
rebase srcRadix destRadix digits
    | srcRadix <= 1                            = Nothing
    | destRadix <= 1                           = Nothing
    | not $ all (isValidDigit srcRadix) digits = Nothing
    | null digits                              = Nothing
    | head digits == Just 0                    = Nothing
    | otherwise                                = Just $
        fromFoldable digits # toUnfoldable # reverse
      where
        fromFoldable :: forall f. Foldable f => f Int -> Int
        fromFoldable = foldl (\number digit -> number * srcRadix + digit) 0

        toUnfoldable :: forall f. Unfoldable f => Int -> f Int
        toUnfoldable = unfoldr (\number -> if number <= 0
            then Nothing
            else Just $ Tuple (number `mod` destRadix) (number / destRadix))

isValidRadix :: Int -> Boolean
isValidRadix radix = radix >= 2

isValidDigit :: Int -> Int -> Boolean
isValidDigit radix digit = 0 <= digit && digit < radix

Tags:

construct:add
construct:boolean
construct:class
construct:data-declaration
construct:divide
construct:export
construct:guarded-expression
construct:if-then-else
construct:import
construct:infix-operator
construct:int
construct:integral-number
construct:lambda
construct:logical-and
construct:method
construct:module
construct:multiply
construct:null
construct:number
construct:parameter
construct:pattern-matching
construct:record
construct:string
construct:underscore-identifier
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
ErikSchierboom commented 1 year ago

Exercise: difference-of-squares

Code

module DifferenceOfSquares (differenceOfSquares, squareOfSum, sumOfSquares) where

import Prelude

import Data.Array (range)
import Data.Foldable (sum)

squareOfSum :: Int -> Int
squareOfSum n =
  sum * sum where sum = n * (n + 1) / 2

sumOfSquares :: Int -> Int
sumOfSquares 0 = 0
sumOfSquares n =
  range 1 n #
  map (\x -> x * x) #
  sum

differenceOfSquares :: Int -> Int
differenceOfSquares n = squareOfSum n - sumOfSquares n

Tags:

construct:add
construct:assignment
construct:backslash
construct:divide
construct:export
construct:import
construct:int
construct:integral-number
construct:lambda
construct:local-binding
construct:module
construct:number
construct:operator-overloading
construct:subtract
construct:variable-shadowing
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions
ErikSchierboom commented 1 year ago

Exercise: diamond

Code

module Diamond
   (rows
   ) where

import Prelude

import Data.Array (reverse, drop, (..))
import Data.Char (toCharCode)
import Data.Enum (enumFromTo)
import Data.String (fromCharArray)

rows ∷ Char → Array String
rows c =
        map (row size) $ forward <> backward
    where
        size ∷ Int  -- size of the diamond, depending on the char
        size = 2*((toCharCode c) - 65)+1
        forward ∷ Array Char
        forward = enumFromTo 'A' c
        backward ∷ Array Char
        backward = drop 1 $ reverse forward
        row ∷ Int → Char → String
        row s x =
            fromCharArray $ map (\i →
                    if i == middle-charNum || i == middle+charNum then
                        x
                    else
                        ' ') $ 0..(s-1)
            where
                charNum = (toCharCode x) - 65
                middle = s/2

Tags:

construct:add
construct:array
construct:char
construct:comment
construct:divide
construct:equivalence
construct:explicit-conversion
construct:function
construct:if-else
construct:import
construct:infix-function
construct:int
construct:integral-number
construct:lambda
construct:logical-or
construct:map
construct:module
construct:multiply
construct:number
construct:parameter
construct:string
construct:subtract
construct:variable
construct:visibility
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
technique:type-conversion
ErikSchierboom commented 1 year ago

Exercise: etl

Code

module Etl (transform) where

import Data.Array (concatMap)
import Data.Map (Map, fromFoldable, toUnfoldable)
import Data.Tuple (Tuple (..))
import Data.Char.Unicode (toLower)
import Prelude (map, (<<<))

type Old = Map Int (Array Char)
type New = Map Char Int

transform :: Old -> New
transform = fromFoldable <<< concatMap transformation <<< toUnfoldable
  where transformation (Tuple val chars) = map (\x -> Tuple (toLower x) val) chars

Tags:

construct:array
construct:char
construct:deductive-reasoning
construct:expression
construct:export
construct:import
construct:invocation
construct:lambda
construct:map
construct:module
construct:name-shadowing
construct:pattern-matching
construct:qualified-name
construct:type
construct:type-alias
construct:where-clause
paradigm:functional
paradigm:logical
paradigm:object-oriented
technique:higher-order-functions
uses:Map
ErikSchierboom commented 1 year ago

Exercise: etl

Code

module Etl
  ( transform
  ) where

import Prelude

import Data.Array
  ( concatMap
  )
import Data.Char.Unicode 
  ( toLower
  )
import Data.Map
  ( Map
  , fromFoldable
  , toUnfoldable
  )
import Data.Tuple
  ( Tuple (..)
  , swap
  )

transform :: Map Int (Array Char) -> Map Char Int 
transform =
  fromFoldable <<<
  concatMap r <<<
  toUnfoldable
  where
    r :: Tuple Int (Array Char) -> Array (Tuple Char Int)
    r (Tuple v cs) = (swap <<< Tuple v <<< toLower) <$> cs

Tags:

construct:char
construct:double-less-than
construct:expression
construct:import
construct:invocation
construct:lambda
construct:module
construct:parameter
construct:pattern-matching
construct:qualified-name
construct:where-clause
construct:word
paradigm:functional
paradigm:higher-order-functions
ErikSchierboom commented 1 year ago

Exercise: largest-series-product

Code

module LargestSeriesProduct (largestProduct) where

import Prelude

import Data.Array (range, slice)
import Data.Int (fromString)
import Data.Maybe (Maybe(..))
import Data.String (Pattern(..), split)
import Data.String.CodeUnits (length)
import Data.Traversable (maximum, product, traverse)

largestProduct ∷ String → Int → Maybe Int
largestProduct s n
  | 0 > n || n > length s = Nothing
  | otherwise = do
    digits ← traverse fromString $ split (Pattern "") s
    let go i = product $ slice i (i + n) digits
    maximum $ go <$> (range 0 $ (_ - n) $ length s)

Tags:

construct:add
construct:boolean
construct:char
construct:do
construct:import
construct:infix-function
construct:int
construct:integral-number
construct:lambda
construct:let
construct:logical-or
construct:module
construct:number
construct:pattern-matching
construct:string
construct:subtract
construct:unicode-char
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
ErikSchierboom commented 1 year ago

Exercise: pascals-triangle

Code

module PascalsTriangle (rows) where

import Prelude

import Data.Array (drop, zipWith)
import Data.Maybe (Maybe(Just, Nothing))

rows :: Maybe Int -> Maybe (Array (Array Int))
rows Nothing = Nothing
rows (Just n)
  | n < 0 = Nothing
  | n == 0 = Just []
  | otherwise = Just $ rows' [1] n

rows' :: Array Int -> Int -> Array (Array Int)
rows' row 1 = [row]
rows' row n =
  let
    nextRow current = zipWith (+) current (drop 1 current)
  in
    [row] <> rows' (nextRow $ [0] <> row <> [0]) (n - 1)

Tags:

construct:array
construct:binding
construct:char
construct:constructor
construct:function
construct:guarded-expression
construct:import
construct:infix-function
construct:int
construct:integral-number
construct:lambda
construct:let
construct:list
construct:minus
construct:module
construct:number
construct:parameter
construct:pattern-matching
construct:subtract
construct:underscore
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions
uses:Data.Array
uses:Data.List
uses:Data.Monoid.Monoid
uses:Data.Monoid.mempty
uses:Data.Monoid.(<>)
uses:Data.Tuple
uses:Data.Tuple.curry
uses:Data.Tuple.uncurry
ErikSchierboom commented 1 year ago

Exercise: collatz-conjecture

Code

module CollatzConjecture
  ( collatz
  ) where

import Prelude

import Data.Int (even)
import Data.Maybe (Maybe(..))

collatz :: Int -> Maybe Int
collatz n = if n <= 0 then Nothing else Just (go n 0) where
    go i acc | i == 1 = acc
             | even i = go (i / 2) (acc + 1)
             | otherwise = go (3*i + 1) (acc + 1)

Tags:

construct:add
construct:boolean
construct:divide
construct:if-then-else
construct:import
construct:int
construct:integral-number
construct:invocation
construct:lambda
construct:pattern-matching
construct:recursion
construct:subtract
construct:where-clause
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
ErikSchierboom commented 1 year ago

Exercise: sum-of-multiples

Code

module SumOfMultiples
  ( sumOfMultiples
  ) where

import Prelude

import Control.MonadZero (guard)
import Data.Array (any, (..))
import Data.Foldable (class Foldable, sum)

sumOfMultiples ∷ ∀ t. Foldable t ⇒ t Int → Int → Int
sumOfMultiples xs cap = sum do
  i ← 1 .. (cap-1)
  guard $ any (\x → i `mod` x == 0) xs
  pure i

Tags:

construct:application
construct:backtick
construct:class
construct:do
construct:forall
construct:function
construct:import
construct:int
construct:integral-number
construct:invocation
construct:lambda
construct:method
construct:module
construct:number
construct:operator
construct:subtract
construct:unicode
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
ErikSchierboom commented 1 year ago

Exercise: sum-of-multiples

Code

module SumOfMultiples
  ( sumOfMultiples
  ) where

import Prelude

import Data.Foldable (sum)
import Data.List.Lazy (iterate, takeWhile)
import Data.Set (Set)
import Data.Set as Set

sumOfMultiples :: Array Int -> Int -> Int
sumOfMultiples multiples limit = map setOfMultiples multiples # Set.unions # sum
  where
    setOfMultiples :: Int -> Set Int
    setOfMultiples start = Set.fromFoldable $ takeWhile (_ < limit) $ iterate (_ + start) start

Tags:

construct:array
construct:backtick-quoted-string
construct:hash
construct:import
construct:invocation
construct:lambda
construct:module
construct:parameter
construct:pattern-matching
construct:set
construct:underscore
construct:where-clause
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
uses:Set
ErikSchierboom commented 1 year ago

Exercise: rna-transcription

Code

module RNATranscription
  ( toRNA
  ) where

import Data.Traversable (traverse)
import Data.Maybe (Maybe(..))
import Data.String (Pattern(..), split, joinWith)
import Prelude ((#), (<#>))

toRNA :: String -> Maybe String
toRNA dna = split (Pattern "") dna # traverse toRNA1 <#> joinWith ""

toRNA1 :: String -> Maybe String
toRNA1 "G" = Just "C"
toRNA1 "C" = Just "G"
toRNA1 "T" = Just "A"
toRNA1 "A" = Just "U"
toRNA1 _   = Nothing

Tags:

construct:#
construct:import
construct:module
construct:pattern-matching
construct:underscore
construct:function
construct:invocation
construct:lambda
construct:parameter
construct:string
construct:top-level-definition
construct:where-clause
paradigm:functional
technique:higher-order-functions
ErikSchierboom commented 1 year ago

This is an automated comment

Hello :wave: Next week we're going to start using the tagging work people are doing on these. If you've already completed the work, thank you! If you've not, but intend to this week, that's great! If you're not going to get round to doing it, and you've not yet posted a comment letting us know, could you please do so, so that we can find other people to do it. Thanks!