私は現在Haskellを学んでいて、現在問題を抱えています。
これは私のコードです:
data Pos = Pos (Int, Int) deriving (Show, Eq)
allCoordinates :: [Pos]
allCoordinates = concat [(zip (allHelper x) [0..8]) | x<-[0..8]]
allHelper ::Int -> [Int]
allHelper x = [x | y<-[0..8]]
その特定のデータ型を使用する必要があり、これが原因で少し問題が発生しています。
コードが次のように記述されている場合、このコードは完全に正常に機能します。
type Pos = (Int, Int)
allCoordinates :: [(Int, Int)]
allCoordinates = concat [(zip (allHelper x) [0..8]) | x<-[0..8]]
しかし、私はこのビットを編集する必要があります:
concat [(zip (allHelper x) [0..8]) | x<-[0..8]]
それが動作するように:
allCoordinates :: [Pos]
それはおそらく単純な問題であり、私は少し精神的なブロックを持っていますが、誰かが助けることができますか?
ありがとうございました
あなたが書く場合:
type Pos = (Int, Int)
お持ちでない新しいタイプの構築:あなたはタイプの別名を構築し、あなたが交換できるようPos
に(Int, Int)
コードに。したがって、署名付きの関数f :: [(Int,Int)]
はf :: [Pos]
。と同等です。
コードをクリーンアップして、次のように書くことができます。
allCoordinates :: [Pos]
allCoordinates = [ (x,y) | x <- [0..8], y <- [0..8]]
またはさらにクリーン(ただし、おそらく理解するのがやや難しい):
allCoordinates :: [Pos]
allCoordinates = (,) <$> [0..8] <*> [0..8]
型シグニチャを使用するという事実の欠点は、その型に多数の関数が定義されている可能性があることです。おそらく、同じ名前(型クラスの場合)で、実装が異なる関数を定義する必要があります。。その場合、データ型を定義できます。
data Pos = Pos (Int,Int)
これで、コンストラクターを使用して新しい型を定義しましたPos
。これで、上記のコードは機能しなくなりますが、生成したタプルでコンストラクターを呼び出すことで簡単に変更できます。そう:
allCoordinates :: [Pos]
allCoordinates = [ Pos (x,y) | x <- [0..8], y <- [0..8]]
1つのコンストラクターで型を定義し、そのコンストラクターに1つのパラメーターがある場合は、を使用できますnewtype
。これで型を定義しましたが、Haskellは内部的にコンストラクターでラップおよびアンラップせず、単にタプルを別の方法で処理するように最適化できます。
newtype Pos = Pos (Int,Int)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加