Difference between revisions of "SML Practice Problems C"

From CSE425S Wiki
Jump to navigation Jump to search
(Created page with "credit: [http://vault.hanover.edu/~skiadas/ Charilaos Skiadas] [https://www.coursera.org/learn/programming-languages/supplement/JXL99/extra-practice-problems Coursera Week 3...")
 
 
(18 intermediate revisions by the same user not shown)
Line 1: Line 1:
credit: [http://vault.hanover.edu/~skiadas/ Charilaos Skiadas]
+
credit: [https://ca.linkedin.com/in/pavel-lepin Pavel Lepin] and [http://vault.hanover.edu/~skiadas/ Charilaos Skiadas]
 +
 
 +
[https://www.coursera.org/learn/programming-languages/supplement/cVK0L/extra-practice-problems Coursera Week 3 Extra Practice Problems]
 +
=Warming Up=
 +
Given that warmups are already not strictly required, it seems strange to call these optional warmups.
 +
 
 +
It is suggested that you complete the curated warmups first and then move on to these practice problems if you want more.
  
[https://www.coursera.org/learn/programming-languages/supplement/JXL99/extra-practice-problems Coursera Week 3 Extra Practice Problems]
 
 
=Code To Implement=
 
=Code To Implement=
{{SMLToImplement|practice3|do_until<br/>factorial<br/>fixed_point<br/>map2<br/>...|practice3}}
+
{{SMLToImplement|practice_c|compose_opt<br>do_until<br/>factorial<br/>fixed_point<br/>map2<br/>app_all<br/>partition<br/>unfold<br/>map<br/>filter<br/>foldl<br/>map_tree<br/>fold_tree<br/>filter_tree|practice_c}}
 +
 
 +
==compose_opt==
 +
Write a function <code>compose_opt : (’b -> ’c option) -> (’a -> ’b option) -> ’a -> ’c option</code> that composes two functions with "optional" values. If either function returns <code>NONE</code>, then the result is <code>NONE</code>.
 +
==do_until==
 +
Write a function <code>do_until : (’a -> ’a) -> (’a -> bool) -> ’a -> ’a</code>. <code>do_until f p x</code> will apply <code>f to x</code> and <code>f</code> again to that result and so on until <code>p x</code> is false. Example: <code>do_until (fn x => x div 2) (fn x => x mod 2 <> 1)</code> will evaluate to a function of type <code>int->int</code> that divides its argument by <code>2</code> until it reaches an odd number. In effect, it will remove all factors of <code>2</code> its argument.
 +
==factorial==
 +
Use <code>do_until</code> to implement <code>factorial</code>.
 +
==fixed_point==
 +
Use <code>do_until</code> to write a function <nowiki>fixed_point: (''a -> ''a) -> ''a -> ''a</nowiki> that given a function <code>f</code> and an initial value <code>x</code> applies <code>f</code> to <code>x</code> until <code>f x = x</code>. (Notice the use of <nowiki>''</nowiki> to indicate equality types.)
 +
 
 +
==map2==
 +
Write a function <code>map2 : (’a -> ’b) -> ’a * ’a -> ’b * ’b</code> that given a function that takes <code>’a</code> values to <code>’b</code> values and a pair of <code>’a</code> values returns the corresponding pair of <code>’b</code> values.
 +
==app_all==
 +
Write a function <code>app_all : (’b -> ’c list) -> (’a -> ’b list) -> ’a -> ’c list</code>, so that: <code>app_all f g x</code> will apply <code>f</code> to every element of the list <code>g x</code> and concatenate the results into a single list. For example, for <code>fun f n = [n, 2 * n, 3 * n]</code>, we have <code>app_all f f 1 = [1, 2, 3, 2, 4, 6, 3, 6, 9]</code>.
 +
==foldr==
 +
Implement <code>[https://smlfamily.github.io/Basis/list.html#SIG:LIST.foldr:VAL List.foldr]</code>
 +
 
 +
==partition==
 +
Write a function <code>partition : (’a -> bool) -> ’a list -> ’a list * ’a list</code> where the first part of the result contains the second argument elements for which the first element evaluates to true and the second part of the result contains the other second argument elements. Traverse the second argument only once.
 +
==unfold==
 +
Write a function <code>unfold : (’a -> (’b * ’a) option) -> ’a -> ’b list</code> that produces a list of <code>’b</code> values given a "seed" of type <code>’a</code> and a function that given a seed produces <code>SOME</code> of a pair of a <code>’b</code> value and a new seed, or <code>NONE</code> if it is done seeding. For example, here is an elaborate way to count down from 5: <code>unfold (fn n => if n = 0 then NONE else SOME(n, n-1)) 5 = [5, 4, 3, 2, 1]</code>.
 +
==factorial==
 +
Use <code>unfold</code> and <code>foldl</code> to implement <code>factorial</code>.
 +
==map==
 +
Implement <code>map</code> using <code>List.foldr</code>.
 +
==filter==
 +
Implement <code>filter</code> using <code>List.foldr</code>.
 +
==foldl==
 +
Implement <code>foldl</code> using <code>foldr</code> on functions. (This is challenging.)
 +
 
 +
==map_tree, fold_tree, filter_tree==
 +
Define a (polymorphic) type for binary trees where data is at internal nodes but not at leaves. Define <code>map</code> and <code>fold</code> functions over such trees. You can define <code>filter</code> as well where we interpret a "false" as meaning the entire subtree rooted at the node with data that produced false should be replaced with a leaf.
  
 
=Test=
 
=Test=
{{SMLUnitTest|practice3|practice3}}
+
{{SMLUnitTest|practice_c|practice_c}}

Latest revision as of 09:03, 9 February 2022

credit: Pavel Lepin and Charilaos Skiadas

Coursera Week 3 Extra Practice Problems

Warming Up

Given that warmups are already not strictly required, it seems strange to call these optional warmups.

It is suggested that you complete the curated warmups first and then move on to these practice problems if you want more.

Code To Implement

file: src/main/sml/practice_c/practice_c.sml Smlnj-logo.png
functions: compose_opt
do_until
factorial
fixed_point
map2
app_all
partition
unfold
map
filter
foldl
map_tree
fold_tree
filter_tree

compose_opt

Write a function compose_opt : (’b -> ’c option) -> (’a -> ’b option) -> ’a -> ’c option that composes two functions with "optional" values. If either function returns NONE, then the result is NONE.

do_until

Write a function do_until : (’a -> ’a) -> (’a -> bool) -> ’a -> ’a. do_until f p x will apply f to x and f again to that result and so on until p x is false. Example: do_until (fn x => x div 2) (fn x => x mod 2 <> 1) will evaluate to a function of type int->int that divides its argument by 2 until it reaches an odd number. In effect, it will remove all factors of 2 its argument.

factorial

Use do_until to implement factorial.

fixed_point

Use do_until to write a function fixed_point: (''a -> ''a) -> ''a -> ''a that given a function f and an initial value x applies f to x until f x = x. (Notice the use of '' to indicate equality types.)

map2

Write a function map2 : (’a -> ’b) -> ’a * ’a -> ’b * ’b that given a function that takes ’a values to ’b values and a pair of ’a values returns the corresponding pair of ’b values.

app_all

Write a function app_all : (’b -> ’c list) -> (’a -> ’b list) -> ’a -> ’c list, so that: app_all f g x will apply f to every element of the list g x and concatenate the results into a single list. For example, for fun f n = [n, 2 * n, 3 * n], we have app_all f f 1 = [1, 2, 3, 2, 4, 6, 3, 6, 9].

foldr

Implement List.foldr

partition

Write a function partition : (’a -> bool) -> ’a list -> ’a list * ’a list where the first part of the result contains the second argument elements for which the first element evaluates to true and the second part of the result contains the other second argument elements. Traverse the second argument only once.

unfold

Write a function unfold : (’a -> (’b * ’a) option) -> ’a -> ’b list that produces a list of ’b values given a "seed" of type ’a and a function that given a seed produces SOME of a pair of a ’b value and a new seed, or NONE if it is done seeding. For example, here is an elaborate way to count down from 5: unfold (fn n => if n = 0 then NONE else SOME(n, n-1)) 5 = [5, 4, 3, 2, 1].

factorial

Use unfold and foldl to implement factorial.

map

Implement map using List.foldr.

filter

Implement filter using List.foldr.

foldl

Implement foldl using foldr on functions. (This is challenging.)

map_tree, fold_tree, filter_tree

Define a (polymorphic) type for binary trees where data is at internal nodes but not at leaves. Define map and fold functions over such trees. You can define filter as well where we interpret a "false" as meaning the entire subtree rooted at the node with data that produced false should be replaced with a leaf.

Test

file: unit_test_practice_c.sml
source folder: src/test/sml/practice_c