Giter Club home page Giter Club logo

recschemes's Introduction

recschemes

These are code samples for my recursion schemes blog posts.

The literate Org files are stored in /org. The Haskell files here are checked in for your convenience but are generated from the Org files.

To render a file to GFM+footnotes, run ./ghost FILE. org-babel generates Haskell source.

These blog entries and code samples are distributed under the CC BY-NC-SA 4.0 license.

recschemes's People

Contributors

patrickt avatar

Stargazers

 avatar Emeka Nkurumeh avatar Simon Charlow avatar Rui Chen avatar Vladimir Ivanov avatar Rujia Liu avatar  avatar Connor Baker avatar ysmull avatar 李红旺 avatar  avatar  avatar soulomoon avatar chaihahaha avatar  avatar  avatar Copper avatar zxchen avatar Gregory Nwosu avatar Alec Hanefeld avatar 工业聚 avatar Patrick Cieplak avatar  avatar Luca Zhang avatar Nebula Lavelle avatar Danny Navarro avatar John avatar Sergei Dolgov avatar Marc-Antoine avatar Tim Kersey avatar Imamura Yutaka avatar Stuart Terrett avatar Colin Barrett avatar Dan Brooks avatar Sasha Bogicevic avatar Hans Roland Senn avatar Daan Rijks avatar Vasiliy Yorkin avatar  avatar Weerasak Chongnguluam avatar Denis Stoyanov avatar Sam Stites avatar Daniel Kahlenberg avatar Tyler Weir avatar

Watchers

 avatar Colin Barrett avatar Gregory Nwosu avatar James Cloos avatar  avatar

recschemes's Issues

Some inconsistencies in futumorphism section

Stop is mentioned a few times but never declared. I think this should be changed to Manual?
Also in 1 snippet, the grow function returns only a 2-tuple, while it should return a 3-tuple (this is corrected in the later snippets).

It's some nitpicking, but this initially confused me while reading through that section 😅.

Change-making problem question

change :: Cent -> Int
change amt = histo go (expand amt) where
  go :: Nat (Attr Nat Int) -> Int
  go Zero = 1
  go curr@(Next attr) = let
    given = compress curr
    validCoins = filter (<= given) coins
    in sum (map (lookup attr) validCoins)

lookup :: Attr Nat a -> Int -> a
lookup cache 1 = attribute cache
lookup cache n = lookup inner (n - 1) where (Next inner) = hole cache

"Here’s the kicker: our above CoAttr definition is equivalent to the Free monad, and Attr (being dual to CoAttr) is the Cofree comonad."

How can change be re-written in terms of Cofree? I pulled in recursion-schemes but I'm having trouble getting this to work:

type Cent = Int

coins = [Cent]

coins = [100,50,25,10,5,1]

change :: Natural -> Natural
change amt = histo go amt where
  go :: Maybe a -> Natural
  go Nothing = 1
  go curr@(Just attr) = let
    given = _curr
    validCoins = filter (<= given) coins
    in sum (map (lookup attr) validCoins)
  lookup cache 0 = _attribute
  lookup cache n = lookup inner (n - 1) where (Just inner) = _hole

Thanks

Errors in code to solve Coin Change Problem

Hi, I stumbled upon your intro series to recursion schemes and so far it is an enlightening read. However, I notice that there are some errors in the code for Coin Change Problem in part 4 of the series.

First, normally Coin Change Problem asks for the number of ways one can make the change of a fixed amount that is insensitive to the order where a coin is being listed. Eg. there are only 2 ways to make a change of amount 6:
[1, 5]
[1, 1, 1, 1, 1, 1]
Note that here [1, 5] and [5, 1] are counted as the same way.

However, the intention of your code seems to be sensitive to the order of the coins. Eg. there are 3 ways to make a change of amount 6:
[1, 5]
[5, 1]
[1, 1, 1, 1, 1, 1]

Secondly, the code to lookup cache is wrong. The code seems to incorrectly assume that the history is stored in such a way that the result of change 0 is stored at the outermost level, result of change 1 is stored at the second outermost level, ..., and the result of change (given - 1) is stored at the innermost level. However, the reverse is true. That is, the result of change (given - 1) is stored at the outermost level and the result of change 0 is stored at the innermost level.

Below is a modified code that correctly solves the Coin Change Problem variant where the order of the coins in the change matters.

change :: Cent -> Int
change amt = histo go (expand amt) where
  go :: Nat (Attr Nat Int) -> Int
  go Zero = 1
  go curr@(Next attr) = let
    given = compress curr
    validCoins = filter (<= given) coins
    in sum (map (lookup attr) validCoins)

lookup :: Attr Nat a -> Int -> a
lookup cache 1 = attribute cache
lookup cache n = lookup inner (n - 1) where (Next inner) = hole cache

Typos in the futumorphism section of Part 4

Thank you for writing this excellent series!

I noticed that starting around here you start using Continue and Stop to refer to the CoAttr constructors in the text and in parts of the horticulture example code, whereas you have defined these constructors as Automatic and Manual.

The `change` function appears not to always give the right answer

When I run the change function from the section on futumorphisms, it reports that there are 3 ways to make change for 10 cents. But it seems like there are four: a dime, two nickels, a nickel and five cents, or ten cents.

That's the only error I see below 15. For numbers greater than 14 I suspect it might always be wrong:

> mapM_ (putStrLn . show) $ map (id &&& change) [0..16]
(0,1)
(1,1)
(2,1)
(3,1)
(4,1)
(5,2)
(6,2)
(7,2)
(8,2)
(9,2)
(10,3)
(11,4)
(12,4)
(13,4)
(14,4)
(15,4)
(16,4)

A few things that might be broken in the blog series

I just discovered your posts about recursion schemes. They are absolutely wonderful. Thank you so much.

I'm not sure whether the following are all in fact problems with the blog; it could be I just missed something. If I should post these somewhere else, please let me know.

The cata laws

In part 2 I'm confused by the laws. The first is stated as an equation: cata In = id. That's clear. But the second is stated as an implication:

-- given alg :: f a -> a
-- and func  :: f a -> f
cata (alg >>> fmap func) =>
   (cata alg) >>> func

Is that => symbol supposed to be =?

The third law's statement is even stranger:

-- given alg  :: f a -> a
-- and func :: f a -> g a
cata (f >>> In) >>> cata g
   ==> cata (f >>> g)

Is that ==> symbol again supposed to be =? And why does it stipulate types for alg and func, without ever using them?

Generalizing cata using para

This happens in section 3 of the blog series.
The code provided is this:

cata' :: Functor f => Algebra f a -> Term f -> a
cata' = para'' (const f)

But f is not defined, except as a type constraint.

Section II appears not to talk about ana

Section III claims Section II defined ana: "In the previous post, we defined ana, the anamorphism ...". Section 1 makes a similar claim. I'm not finding it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.