1

私は、Scala と Haskell の両方で Martin Odersky の「Functional Programming Principles in Scala」のコースラ コースの演習を行っています。「関数として設定」の演習では、「toString」関数を定義しました。

import Data.List (intercalate)

type Set = Int -> Bool

contains :: Set -> Int -> Bool
contains s elem = s elem

bound = 1000

toString :: Set -> String
toString s =
    let xs = [(show x) | x <- [(-bound) .. bound], contains s x]
    in "{" ++ (intercalate "," xs) ++ "}"

-- toString (\x -> x > -3 && x < 10)
-- => "{-2,-1,0,1,2,3,4,5,6,7,8,9}"

次のように定義できると便利です。

instance Show Set where
    show Set = ...

ただし、定義では Set を表す関数 thqt を参照して呼び出す必要があります (つまり、「toString」関数を参照してください)。

「Show Set」を定義するために使用できる Haskell マジックはありますか?

フィードバックに基づく更新:

提案された 2 つの解決策を 試し、Haskell の `data` と `newtype` の違いtypeを読んだ後、またはを 使用しnewtypeても同じ「パフォーマンス」が得られるようですが (つまり、上記のリンクを読んでください)、その「newtype」はより強力なタイプ セーフを提供します。例:として定義されている場合Int -> Bool、取る関数に任意の関数を渡すことができますが、渡す必要type Set = Int -> Boolがあります。Set'newtype Set' = Set' (Int -> Bool)

{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}

import Data.List (intercalate)

bound = 1000

-- ALTERNATE #1

type Set = Int -> Bool

contains :: Set -> Int -> Bool
contains s elem = s elem

intersect :: Set -> Set -> Set
intersect s t = \x -> s x && t x

toString :: Set -> String
toString s =
    let xs = [(show x) | x <- [(-bound) .. bound], contains s x]
    in "{" ++ (intercalate "," xs) ++ "}"

instance Show Set where show = toString

-- ALTERNATE #2

newtype Set' = Set' (Int -> Bool)

contains' :: Set' -> Int -> Bool
contains' (Set' s) elem = s elem

intersect' :: Set' -> Set' -> Set'
intersect' (Set' s) (Set' t) = Set' (\x -> s x && t x)

instance Show Set' where
    show (Set' s) =
        let xs = [(show x) | x <- [(-bound) .. bound], s x]
        in "{" ++ (intercalate "," xs) ++ "}"

anyIntBoolFun1 = \x -> -10 < x
anyIntBoolFun2 = \x ->   x < 0
setIntBoolFun1 = Set' anyIntBoolFun1
setIntBoolFun2 = Set' anyIntBoolFun2

main = do
    putStrLn $ show $ intersect  anyIntBoolFun1 anyIntBoolFun2
    putStrLn $ show $ intersect' setIntBoolFun1 setIntBoolFun2

-- *Main> main
-- {-9,-8,-7,-6,-5,-4,-3,-2,-1}
-- {-9,-8,-7,-6,-5,-4,-3,-2,-1}
4

2 に答える 2