Jump to content

Monads/Writer monad: Difference between revisions

{{header|AppleScript}}
No edit summary
({{header|AppleScript}})
Line 1:
[[Category:Monads]]
 
The Writer monad is a codingprogramming design pattern which makes it possible to compose functions which return their resultsresult values combinedpaired with a log string. The final result of a composed function yields both the resultinga value, and a concatenation of the logs from each component function application.
 
Demonstrate in your programming language the following:
Line 9:
# Derive Writer monad versions of each of these functions
# Apply a composition of the Writer versions of root, addOne, and half to the integer 5, deriving both a value for the Golden Ratio φ, and a concatenated log of the function applications (starting with the initial value, and followed by the application of root, etc.)
 
 
=={{header|AppleScript}}==
 
{{trans|JavaScript}}
 
<lang>-- WRITER MONAD FOR APPLESCRIPT
 
-- How can we compose functions which take simple values as arguments
-- but return an output value which is paired with a log string ?
 
-- We can prevent functions which expect simple values from choking on log-wrapped output (from nested functions)
-- by writing Unit/Return() and Bind() for the Writer monad in AppleScript
 
on run {}
-- Derive logging versions of three simple functions, pairing
-- each function with a particular comment string
-- (a -> b) -> (a -> (b, String))
set wRoot to writerVersion(root, "obtained square root")
set wSucc to writerVersion(succ, "added one")
set wHalf to writerVersion(half, "divided by two")
loggingHalfOfRootPlusOne(5)
end run
 
 
-- THREE SIMPLE FUNCTIONS
on root(x)
x ^ (1 / 2)
end root
 
on succ(x)
x + 1
end succ
 
on half(x)
x / 2
end half
 
-- DERIVE A LOGGING VERSION OF A FUNCTION BY COMBINING IT WITH A
-- LOG STRING FOR THAT FUNCTION
-- (SEE 'on run()' handler at top of script)
-- (a -> b) -> String -> (a -> (b, String))
on writerVersion(f, strComment)
script
on call(x)
{value:sReturn(f)'s call(x), comment:strComment}
end call
end script
end writerVersion
 
 
-- DEFINE A A COMPOSITION OF THE SAFE VERSIONS
on loggingHalfOfRootPlusOne(x)
logCompose([my wHalf, my wSucc, my wRoot], x)
end loggingHalfOfRootPlusOne
 
 
-- Mondaic UNIT/RETURN and BIND functions for the writer monad
on writerUnit(a)
try
set strValue to ": " & a as string
on error
set strValue to ""
end try
{value:a, comment:"Initial value" & strValue}
end writerUnit
 
on writerBind(recWriter, wf)
set recB to wf's call(value of recWriter)
set v to value of recB
try
set strV to " -> " & (v as string)
on error
set strV to ""
end try
{value:v, comment:(comment of recWriter) & linefeed & (comment of recB) & strV}
end writerBind
 
-- THE TWO HIGHER ORDER FUNCTIONS ABOVE ENABLE COMPOSITION OF
-- THE LOGGING VERSIONS OF EACH FUNCTION
on logCompose(lstFunctions, varValue)
reduceRight(lstFunctions, writerBind, writerUnit(varValue))
end logCompose
 
-- xs: list, f: function, a: initial accumulator value
-- the arguments available to the function f(a, x, i, l) are
-- v: current accumulator value
-- x: current item in list
-- i: [ 1-based index in list ] optional
-- l: [ a reference to the list itself ] optional
on reduceRight(xs, f, a)
set sf to sReturn(f)
repeat with i from length of xs to 1 by -1
set a to sf's call(a, item i of xs, i, xs)
end repeat
end reduceRight
 
-- Unit/Return and bind for composing handlers in script wrappers
-- lift 2nd class function into 1st class wrapper
-- handler function --> first class script object
on sReturn(f)
script
property call : f
end script
end sReturn
 
-- return a new script in which function g is composed
-- with the f (call()) of the Mf script
-- Mf -> (f -> Mg) -> Mg
on sBind(mf, g)
script
on call(x)
sReturn(g)'s call(mf's call(x))
end call
end script
end sBind</lang>
 
{{Out}}
 
<pre>{
value:1.61803398875,
comment:"Initial value: 5\n
obtained square root -> 2.2360679775\n
added one -> 3.2360679775\n
divided by two -> 1.61803398875"
}</pre>
 
 
=={{header|EchoLisp}}==
9,659

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.