Things
This commit is contained in:
commit
205dcb21ae
5 changed files with 342 additions and 0 deletions
58
flake.lock
generated
Normal file
58
flake.lock
generated
Normal file
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": "nixpkgs-lib"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1727826117,
|
||||
"narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1729880355,
|
||||
"narHash": "sha256-RP+OQ6koQQLX5nw0NmcDrzvGL8HDLnyXt/jHhL1jwjM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "18536bf04cd71abd345f9579158841376fdd0c5a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-lib": {
|
||||
"locked": {
|
||||
"lastModified": 1727825735,
|
||||
"narHash": "sha256-0xHYkMkeLVQAMa7gvkddbPqpxph+hDzdu1XdGPJR+Os=",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/NixOS/nixpkgs/archive/fb192fec7cc7a4c26d51779e9bab07ce6fa5597a.tar.gz"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
20
flake.nix
Normal file
20
flake.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
inputs = {
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
};
|
||||
|
||||
outputs = inputs @ {flake-parts, ...}:
|
||||
flake-parts.lib.mkFlake {inherit inputs;} {
|
||||
systems = ["x86_64-linux"];
|
||||
perSystem = {pkgs, ...}: {
|
||||
devShells.default = pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
cabal-install
|
||||
ghc
|
||||
haskell-language-server
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
48
src/ApplicativeChapter.hs
Normal file
48
src/ApplicativeChapter.hs
Normal file
|
@ -0,0 +1,48 @@
|
|||
{-# LANGUAGE NoImplicitPrelude #-}
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
{-# OPTIONS_GHC -Wno-unused-top-binds #-}
|
||||
|
||||
module ApplicativeChapter () where
|
||||
|
||||
import Data.Function (const)
|
||||
import GHC.Base ( id, Functor(..) )
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Data.Function (($))
|
||||
import Data.List (zipWith)
|
||||
|
||||
liftA2 :: ApplicativeChapter.Applicative f => (a -> b -> c) -> f a -> f b -> f c
|
||||
liftA2 f x = (<*>) (fmap f x)
|
||||
|
||||
class Functor f => Applicative f where
|
||||
pure :: a -> f a
|
||||
infixl 4 <*>, *>
|
||||
(<*>) :: f (a -> b) -> f a -> f b
|
||||
|
||||
(*>) :: f a -> f b -> f b
|
||||
a1 *> a2 = (id <$ a1) <*> a2
|
||||
|
||||
(<*) :: f a -> f b -> f a
|
||||
(<*) = liftA2 const
|
||||
|
||||
-- ??
|
||||
|
||||
-- Maybe is Applicative
|
||||
|
||||
instance Applicative Maybe where
|
||||
(<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b
|
||||
(<*>) Nothing _ = Nothing
|
||||
(<*>) (Just f) x = fmap f x
|
||||
|
||||
pure :: a -> Maybe a
|
||||
pure = Just
|
||||
|
||||
-- List can be Applicative in 2 different ways
|
||||
|
||||
newtype ZipList a = ZipList { getZipList :: [a] }
|
||||
|
||||
instance Applicative ZipList where
|
||||
pure :: a -> ZipList a
|
||||
pure a = ZipList [a]
|
||||
|
||||
(<*>) :: ZipList (a -> b) -> ZipList a -> ZipList b
|
||||
(ZipList gs) <*> (ZipList xs) = ZipList (zipWith ($) gs xs)
|
110
src/FunctorChapter.hs
Normal file
110
src/FunctorChapter.hs
Normal file
|
@ -0,0 +1,110 @@
|
|||
{-# LANGUAGE NoImplicitPrelude #-}
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
{-# OPTIONS_GHC -Wno-unused-top-binds #-}
|
||||
|
||||
module FunctorChapter () where
|
||||
|
||||
import Data.Either (Either(..))
|
||||
import Data.Function (($))
|
||||
import Data.Int
|
||||
import Data.Maybe ( Maybe, Maybe(..) )
|
||||
|
||||
const :: a -> b -> a
|
||||
const a _ = a
|
||||
|
||||
class Functor f where
|
||||
fmap :: (a -> b) -> f a -> f b
|
||||
(<$) :: a -> f b -> f a
|
||||
{-# MINIMAL fmap #-}
|
||||
(<$) a = fmap (const a)
|
||||
|
||||
-- 1
|
||||
instance Functor (Either e) where
|
||||
fmap :: (a -> b) -> Either e a -> Either e b
|
||||
fmap f (Right ex) = Right $ f ex
|
||||
fmap _ (Left x) = Left x
|
||||
|
||||
(.) :: (b -> c) -> (a -> b) -> (a -> c)
|
||||
(.) fbc fab x = fbc (fab x)
|
||||
|
||||
-- 1bis
|
||||
instance Functor ((->) e) where
|
||||
fmap :: (a -> b) -> (e -> a) -> (e -> b)
|
||||
fmap fab fea = fab . fea
|
||||
|
||||
-- 2
|
||||
instance Functor ((,) e) where
|
||||
fmap :: (a -> b) -> (e, a) -> (e, b)
|
||||
fmap f (e, bx) = (e, f bx)
|
||||
|
||||
data Pair a = Pair a a
|
||||
|
||||
instance Functor Pair where
|
||||
fmap :: (a -> b) -> Pair a -> Pair b
|
||||
fmap f (Pair ax ay) = Pair (f ax) (f ay)
|
||||
|
||||
-- Differences: Pair is a concrete type while ((,) e) isn't
|
||||
-- Moreover both the wrapped values in Pair have the same type
|
||||
-- and we have to wrap both if we want to return a Pair b
|
||||
-- Instead for ((,) e) we don't know anything about e so we
|
||||
-- cannot apply any function to it
|
||||
|
||||
data ITree a = Leaf (Int -> a)
|
||||
| Node [ITree a]
|
||||
|
||||
-- 3
|
||||
|
||||
instance Functor [] where
|
||||
fmap :: (a -> b) -> [] a -> [] b
|
||||
fmap fab (x:xs) = fab x : fmap fab xs
|
||||
fmap _ [] = []
|
||||
|
||||
instance Functor ITree where
|
||||
fmap :: (a -> b) -> ITree a -> ITree b
|
||||
fmap fab (Leaf fia) = Leaf $ fab . fia
|
||||
fmap fab (Node ts) = Node (fmap (fmap fab) ts)
|
||||
|
||||
-- 4 ???
|
||||
-- data Foo a = Foo
|
||||
|
||||
-- instance Functor Foo where
|
||||
-- fmap :: (b -> c) -> Foo b -> Foo c
|
||||
-- fmap fbc (Foo) = Foo
|
||||
|
||||
-- 5
|
||||
newtype ListMaybe a = ListMaybe [Maybe a]
|
||||
|
||||
instance Functor Maybe where
|
||||
fmap :: (a -> b) -> Maybe a -> Maybe b
|
||||
fmap _ Nothing = Nothing
|
||||
fmap fab (Just a) = Just $ fab a
|
||||
|
||||
instance Functor ListMaybe where
|
||||
fmap :: (a -> b) -> ListMaybe a -> ListMaybe b
|
||||
fmap fab (ListMaybe ms) = ListMaybe (fmap (fmap fab) ms)
|
||||
|
||||
-- 1
|
||||
|
||||
data Maybe' a = Just' a | Nothing'
|
||||
|
||||
instance Functor Maybe' where
|
||||
fmap :: (a -> b) -> Maybe' a -> Maybe' b
|
||||
fmap _ _ = Nothing'
|
||||
|
||||
-- fmap id = \x -> Nothing' != id
|
||||
-- fmap f . fmap g = \x -> Nothing' = fmap (f . g)
|
||||
|
||||
-- 2
|
||||
-- (evilFmap id) [1] = [1 1]
|
||||
-- then evilFmap id != id
|
||||
|
||||
-- fmap id x:xs =
|
||||
-- (id x):(id x):(fmap id xs) = # function application
|
||||
-- x:x:(fmap id xs) = # associativity
|
||||
-- x:( x:(fmap id xs) ) = # definition (list, well defined Functor []): fmap id xs = x: fmap id xs
|
||||
-- x:( fmap id (x:xs) ) =
|
||||
-- x:( id (x:xs) ) = # identity law substitution (fmap id = id)
|
||||
-- (x:) . (id $ (:) x xs) = # rewrite using composition (.)
|
||||
-- (x:) . id . (x:) xs = # rewrite using composition (.)
|
||||
-- (x:) . id . (x:) = # eta reduction
|
||||
-- != id
|
106
typeclassopedia.cabal
Normal file
106
typeclassopedia.cabal
Normal file
|
@ -0,0 +1,106 @@
|
|||
cabal-version: 3.0
|
||||
-- The cabal-version field refers to the version of the .cabal specification,
|
||||
-- and can be different from the cabal-install (the tool) version and the
|
||||
-- Cabal (the library) version you are using. As such, the Cabal (the library)
|
||||
-- version used must be equal or greater than the version stated in this field.
|
||||
-- Starting from the specification version 2.2, the cabal-version field must be
|
||||
-- the first thing in the cabal file.
|
||||
|
||||
-- Initial package description 'typeclassopedia' generated by
|
||||
-- 'cabal init'. For further documentation, see:
|
||||
-- http://haskell.org/cabal/users-guide/
|
||||
--
|
||||
-- The name of the package.
|
||||
name: typeclassopedia
|
||||
|
||||
-- The package version.
|
||||
-- See the Haskell package versioning policy (PVP) for standards
|
||||
-- guiding when and how versions should be incremented.
|
||||
-- https://pvp.haskell.org
|
||||
-- PVP summary: +-+------- breaking API changes
|
||||
-- | | +----- non-breaking API additions
|
||||
-- | | | +--- code changes with no API change
|
||||
version: 0.1.0.0
|
||||
|
||||
-- A short (one-line) description of the package.
|
||||
-- synopsis:
|
||||
|
||||
-- A longer description of the package.
|
||||
-- description:
|
||||
|
||||
-- URL for the project homepage or repository.
|
||||
homepage: https://github.com/aciceri/typeclassoopedia
|
||||
|
||||
-- The license under which the package is released.
|
||||
license: GPL-3.0-only
|
||||
|
||||
-- The file containing the license text.
|
||||
license-file: LICENSE
|
||||
|
||||
-- The package author(s).
|
||||
author: Andrea Ciceri
|
||||
|
||||
-- An email address to which users can send suggestions, bug reports, and patches.
|
||||
maintainer: andrea.ciceri@autistici.org
|
||||
|
||||
-- A copyright notice.
|
||||
-- copyright:
|
||||
build-type: Simple
|
||||
|
||||
-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README.
|
||||
extra-doc-files: CHANGELOG.md
|
||||
|
||||
-- Extra source files to be distributed with the package, such as examples, or a tutorial module.
|
||||
-- extra-source-files:
|
||||
|
||||
common warnings
|
||||
ghc-options: -Wall
|
||||
|
||||
library
|
||||
-- Import common warning flags.
|
||||
import: warnings
|
||||
|
||||
-- Modules exported by the library.
|
||||
exposed-modules: FunctorChapter, ApplicativeChapter
|
||||
|
||||
-- Modules included in this library but not exported.
|
||||
-- other-modules:
|
||||
|
||||
-- LANGUAGE extensions used by modules in this package.
|
||||
-- other-extensions:
|
||||
|
||||
-- Other library packages from which modules are imported.
|
||||
build-depends: base ^>=4.18.2.1
|
||||
|
||||
-- Directories containing source files.
|
||||
hs-source-dirs: src
|
||||
|
||||
-- Base language which the package is written in.
|
||||
default-language: Haskell2010
|
||||
|
||||
test-suite typeclassopedia-test
|
||||
-- Import common warning flags.
|
||||
import: warnings
|
||||
|
||||
-- Base language which the package is written in.
|
||||
default-language: Haskell2010
|
||||
|
||||
-- Modules included in this executable, other than Main.
|
||||
-- other-modules:
|
||||
|
||||
-- LANGUAGE extensions used by modules in this package.
|
||||
-- other-extensions:
|
||||
|
||||
-- The interface type and version of the test suite.
|
||||
type: exitcode-stdio-1.0
|
||||
|
||||
-- Directories containing source files.
|
||||
hs-source-dirs: test
|
||||
|
||||
-- The entrypoint to the test suite.
|
||||
main-is: Main.hs
|
||||
|
||||
-- Test dependencies.
|
||||
build-depends:
|
||||
base ^>=4.18.2.1,
|
||||
typeclassopedia
|
Loading…
Add table
Reference in a new issue