2013-11-01 4 views
7

私はHaskellを新しくしましたが、実際に新しいタイプを定義する必要はなく、すでに存在するタイプのサブセットでしか定義されていない関数を定義できるかどうかを知りたいと思います。既存の型のサブセットに関数を定義することは可能ですか?

例:整数(偶数など)だけを受け入れ、返す関数を作成したいとします。その数字は次のようになります。

squared :: 2*Integer -> Integer 
squared n = n*n 

上記の2行はうまくいきません。

私はこのようにそれを書くことができます知っている:

squared' :: Integer -> Integer 
squared' n 
    | (even n) = n*n 
    | otherwise = error "n is not even!" 

または類似した何かが、私は非稼働の例のようなものが同様に可能であるかどうかを知りたいです。 ...

私はこの質問は完全に愚かではないことを願う(または既に回答された)が、私は本当に(その種類の困難にも返事をして検索)まだハスケルの多くを知らない

+0

それが依存型のためにHaskellの – viorior

答えて

12

一般的にいいえ。このようなことはサブセット型と呼ばれ、Haskellにはない従属型の特徴です。通常、それは値が何らかの性質を満たすという証拠で値をボクシングすることによって実装されますが、ハスケルに証明の概念がないので、私たちは立ち往生しています。

通常、偽装する方法は「スマートコンストラクタ」です。その後、

newtype Even = Even {unEven :: Integer} deriving (Eq, Show, Ord) 

toEven :: Integer -> Maybe Even 
toEven a | even a = Just $ Even a 
     | otherwise = Nothing 

そしてEvenコンストラクタを非表示にします。

本当にそれが欲しいなら、依存型(CoqとAgdaは気にする)を持つHas​​kellと相互に作用する言語に切り替えることができます。

+0

万歳では容易ではありません!依存型の概念が少し混乱している場合は、このビデオをご覧ください:http://vimeo.com/77168227。それは、型のレベルでリストの長さなどの余分な情報を提供するために従属型を使用する良い例を提供します。 – Tetigi

1

ラップのnewtypeにおけるサブセット

+2

これはうまくいかず、 '1 :: EvenInteger'が1を偶数の領域に挿入します – jozefg

+0

Erg ...そうです。構文上の醜さに対処することができれば、この解決策は 'Num'を導き出すことなく機能することができます。これは私が病気より治療法が悪いと言うだろう1つのケースだろう:( –

1
newtype EvenInteger = EvenInteger { 
    unEvenInteger :: Integer 
} deriving (Show, Eq, Ord, Num) 

mkEvenInteger :: Integer -> Maybe EvenInteger 
mkEvenInteger n = case n % 2 of 
    0 -> Just $ EvenInteger n 
    _ -> Nothing 

squared :: EvenInteger -> EvenInteger 
squared n = n * n 

他の箇所で述べたように一つの可能​​性は

newtype Even n = Even n 
getEven (Even n) = 2*n 

squared :: Num n => Even n -> Even n 
squared (Even n) = Even (2*n*n) 
1

なり、LiquidHaskellのように改良型は、これを発現することができます。あなたがここでそれを差し込むことによって、これを試してみることができ

module Evens where 

{[email protected] type Even = {v:Int | v mod 2 = 0} @-} 

{[email protected] square :: Even -> Int @-} 
square :: Int -> Int 
square n = n * n 

-- calling the function: 
yup = square 4 
-- nope = square 3 -- will not compile if this is uncommented 

:ここでのように見えるものですhttp://goto.ucsd.edu:8090/index.html

関連する問題