計算機科学のブログ

関数型プログラミングの基礎 ファーストクラス関数 引数としての関数 引数としてのラムダ式、カスタムソート、タプルのリスト、組み込み関数、Data、Listモジュール、sortBy関数

入門Haskellプログラミング (Will Kurt(著)、株式会社クイープ(監修、翻訳)、翔泳社)のUNIT1(関数型プログラミングの基礎)、LESSON 4(ファーストクラス関数)、4.1(引数としての関数)、引数としてのラムダ式のクイックチェック4-1、カスタムソートのクイックチェック4-2の解答を求めてみる。

コード

import Data.List

names :: [([Char], [Char])]
names = [
    ("Ian", "Curtis"),
    ("Bernard", "Sumner"),
    ("Peter", "Hook"),
    ("Stephen", "Morris"),
    ("Ian", "Curtis"),
    ("Bernard", "Hook")
 ]
compareLastNames :: (Ord b, Ord a) => (a, b) -> (a, b) -> Ordering
compareLastNames name1 name2 = 
    let
        lastName1 = snd name1
        lastName2 = snd name2
    in
        if lastName1 > lastName2
        then GT
        else
            if lastName1 < lastName2
            then LT
            else
                let
                    firstName1 = fst name1
                    firstName2 = fst name2
                in
                    if firstName1 > firstName2
                    then GT
                    else
                        if firstName1 < firstName2
                        then LT
                        else EQ

入出力結果(Terminal, Zsh)

% ghci
GHCi, version 8.10.4: https://www.haskell.org/ghc/  :? for help
macro 'doc' overwrites builtin command.  Use ':def!' to overwrite.
(0.00 secs, 0 bytes)
(0.00 secs, 0 bytes)
Loaded GHCi configuration from /.../.ghc/ghci.conf
Prelude
λ> :load sample1.hs 
[1 of 1] Compiling Main             ( sample1.hs, interpreted )
Ok, one module loaded.
(0.03 secs,)
*Main
λ> ifEven (\x -> x*3) 0
0
it :: Integral a => a
(0.04 secs, 62,424 bytes)
*Main
λ> ifEven (\x -> x*3) 1
1
it :: Integral a => a
(0.01 secs, 60,008 bytes)
*Main
λ> ifEven (\x -> x*3) 2
6
it :: Integral a => a
(0.00 secs, 60,128 bytes)
*Main
λ> ifEven (\x -> x*3) -1

<interactive>:5:1: error:
    • Non type-variable argument in the constraint: Num (a -> a)
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall a. (Integral a, Num (a -> a)) => a -> a
(0.00 secs,)
*Main
λ> ifEven (\x -> x*3) (-1)
-1
it :: Integral a => a
(0.00 secs, 60,832 bytes)
*Main
λ> ifEven (\x -> x*3) (-2)
-6
it :: Integral a => a
(0.00 secs, 60,952 bytes)
*Main
λ> :load sample2
[1 of 1] Compiling Main             ( sample2.hs, interpreted )
Ok, one module loaded.
(0.01 secs,)
*Main
λ> names
[("Ian","Curtis"),("Bernard","Sumner"),("Peter","Hook"),("Stephen","Morris"),("Ian","Curtis"),("Bernard","Hook")]
it :: [([Char], [Char])]
(0.00 secs, 150,704 bytes)
*Main
λ> sort
sort    sortBy  sortOn
λ> sortBy compareLastNames names 
[("Ian","Curtis"),("Ian","Curtis"),("Bernard","Hook"),("Peter","Hook"),("Stephen","Morris"),("Bernard","Sumner")]
it :: [([Char], [Char])]
(0.02 secs, 149,936 bytes)
*Main
λ> :q
Leaving GHCi.
%