2017-03-08 7 views
-2

私はLYAHを経てきましたが、ハスケルの紹介はあまり良くありません。リチャード・バードの「Haskellを使った関数型プログラミング入門」を勧めた「Haskellへの優しい導入」に出くわしました。それは私が今読んでいる本です。第3章ではNat型のデータ型を作成し、基本的な算術演算を実装しています。ナチュラルナンバー算術をゼロから実装する際のトラブル

これは私が今まで書かれているコードです:

module Main where 
import Prelude hiding ((^^)) 

data Nat = Zero | Succ Nat 
     deriving (Eq, Ord, Show) 
xx :: Nat -> Nat -> Nat 
m `xx` Zero = Zero 
m `xx` Succ n = (m `xx` n) `add` m 

(^^) :: Nat -> Nat -> Nat 
m ^^ Zero = Succ Zero 
m ^^ Succ n = (m ^^ n) `xx` m 

add :: Nat -> Nat -> Nat 
m `add` Zero = m 
m `add` Succ n = Succ(m `add` n) 

factsu :: Nat -> Nat 
factsu Zero  = Succ Zero 
factsu (Succ n) = Succ n `xx` factsu n 

--Zero = 0 

showNat :: Nat -> String 
showNat Zero = "Zero" 
showNat (Succ Zero) = "Succ Zero" 
showNat (Succ (Succ n)) = "Succ (" ++ showNat (Succ n) ++ ")" 

main :: IO() 
main = return() 

これは何が起こるかです:

factsu Zero 
Succ Zero 
it :: Nat 

私は成功回数とゼロを定義するにはどうすればよいですか?

+2

* SuccとZeroを*定義するとどういう意味ですか?あなたはあなたのファイルにそれらを定義しました... –

+0

@WillemVanOnsem私は彼らが文字列として解釈されていると思います。 – learninghaskell

+2

いいえ、それらを次のように定義しました: 'data Nat = Zero |サックナット。 'Nat'は' Show'から派生しているので、例えば 'show(Succ Nat)'を文字列に変換します。あなたは '' Succ Zero''を '' Succ Zero''に構文解析できるように 'Read'から派生させることもできます。 –

答えて

3

は、しかし、私は「私が等しい0からZeroをしたい」ゼロは根本的な問題は、あなたが何を意味です0

等しくなるようにしたいです。それを読むのが「私はZero == (0 :: Integer)がほしい」かもしれませんが、それは不可能です。Zero0 :: Integerのタイプが異なります。Zeroは実際には独自のものです。あなただけのGHCiのは...「0」として

GHCi> Zero 
0 

Zeroを印刷したい場合は、一方

natToInteger :: Nat -> Integer 
integerToNat :: Integer -> Maybe Nat 

:何ももちろん、それらの間の相互変換機能を定義するから、あなたを停止しません。 ..あなたが必要とするのは、Showというカスタムのインスタンスです.karakfaとleftaroundaboutはin the commentsを提案しています。しかし、実際にはZeroの内容は変更されません。あなたはそれが表示される方法を変えるだけです。

最後に、第三の可能性はあなたのNat秒間数値リテラル構文を使用したいということです:

あなたが Nat Numインスタンスを与えれば、実際に可能である
GHCi> 0 + 2 :: Nat 
2 
it :: Nat 

。しかし、(-)は部分的であり、negateの妥当な実装はありません(ちなみに、Maybeを上記のintegerToNatの署名に入れている理由もあります)。また、Showの場合と同様に、Numインスタンスを追加しても、実質的にはNatの内容は変更されません。特に、数字のリテラル構文は構文だけです。

(あなたは物事はあなたが彼らと何ができるかによって特徴づけられるという観点を取る場合は、「本質的」で私が何を意味するか疑問かもしれません。。しかし、我々はあまりにも横道にそれる前に、私はここで停止します)

+0

私は間違いなく3番目のケースを意味します、私はそれを実装しようとします。 – learninghaskell

+1

第3のポイントは、 'Num'が' SemiRing'で階層構造に分割されたことを願っています。 class SemiGroup aのようなもの{zero :: a、(+):: a - > a} '、' class SemiGroup a => a {negate :: a - > a、 :a - > a - > a} '、'クラスSemiRing a、> a class a(SemiRing a、Group a) => IntegralDomain a {div :: a - > a - > a} 'のどこかで{aInteger :: Integer - > a}'、 'クラスリングa =>を呼び出します。 – Alec

+2

@Alec適切に細分化されたクラス階層がどれほど苦労しているかを知りたいときはいつでも[数値プレリュード](https://hackage.haskell.org/package/numeric-prelude)があります。 –

関連する問題