2016-11-25 21 views
0

Preludeで以下のHaskellコード(here)で定義されている関数の使い方を理解しようとしています。これらの関数を 'List'型に使用する方法

module List 
    where 

data List a = Nil 
      | Cons a (List a) 

listLength :: List a -> Int 
listLength Nil = 0 
listLength (Cons x xs) = 1 + listLength xs 

{- 
listHead :: List a -> Maybe a 
listHead Nil = Nothing 
listHead (Cons x xs) = Just x 

listTail :: List a -> Maybe (List a) 
listTail Nil = Nothing 
listTail (Cons x xs) = Just xs 
-} 
listHead :: List a -> a 
listHead (Cons x xs) = x 

listTail :: List a -> List a 
listTail (Cons x xs) = xs 

listFoldl :: (a -> b -> a) -> a -> List b -> a 
listFoldl f c Nil = c 
listFoldl f c (Cons x xs) = listFoldl f (f c x) xs 

listFoldr :: (a -> b -> b) -> b -> List a -> b 
listFoldr f c Nil = c 
listFoldr f c (Cons x xs) = f x (listFoldr f c xs) 

ghci List.hsコマンドを使用してロードしました。

次に、私が使用しようとしている方法は、listHeadです。

*List> listHead (List 1:2:[]) 

<interactive>:7:11: Not in scope: data constructor `List' 

または、次のように:

*List> listHead ('a':'b':[]) 

<interactive>:11:11: 
    Couldn't match expected type `List a0' with actual type `[Char]' 
    In the first argument of `listHead', namely `('a' : 'b' : [])' 
    In the expression: listHead ('a' : 'b' : []) 
    In an equation for `it': it = listHead ('a' : 'b' : []) 

誰もがGHCiの中でこのコードを使用する方法について説明していただけますか?ありがとう!

答えて

2

あなたは、カスタムで定義されているConsNilデータコンストラクタを使用してList Sを構築することになっている:あなたが構築するためにListを使用することはできませんので

data List a = Nil 
      | Cons a (List a) 

最初のエラー、Not in scope: data constructor `List'は、起こりました値(Listは型コンストラクタ、List aは型です)。あなたが実際にしたいことはある:あなたがList Char値を構築するために、定期的なリストのコンストラクタを使用する(:)[]をしようとしているため、2番目のエラー

listHead (Cons 1 (Cons 2 Nil))) 

Couldn't match expected type `List a0' with actual type `[Char]'、起こりました。 []の代わりに(:)Nilの代わりにConsを使用する必要があります。

3

:演算子と[]構成子は、Haskellのビルトインリスト型に固有のものです。つまり、それらを使ってある種の値[a]を構成するためにのみ使用できます。しかし、あなたがここに持っている関数は、この標準的なリスト型を扱わず、ローカルで定義されたListコンテナを扱います。このようなリストを作成するには、:をそれぞれConsと置き換え、それぞれ[]Nilに置き換える必要があります。 Consは中置演算子ではないため、a:b(:) a bとして書き直す必要があります。たとえば、[Int]リスト1:2:[](:) 1 ((:) 2 [])となり、これはCons 1 (Cons 2 Nil)に相当します。

これらのカスタムリストは、それらの機能のいずれかに供給できます。

*List> listHead $ Cons 1 (Cons 2 Nil) 
1 

もちろんこれは醜いですが、そのListタイプのみが教育目的のために導入されます。実際には、標準[]タイプを使用するか、より良いコンストラクタを使用します。たとえば、あなたが:のように自分自身を中置コンストラクタを定義することができます。

:それと

infixr 6 :& 
data List' a = N | a :& List' a 

をあなただけの代わりに

*List> list'Head $ 1 :& 2 :& N 

を行うことができ、あなたはGHCがあなたのカスタムリストの種類について[]構文を受け入れる作ることができます

{-# LANGUAGE OverloadedLists, TypeFamilies #-} 

import GHC.Exts (IsList(..)) 

instance IsList (List l) where 
    type Item (List l) = l 
    fromList [] = Nil 
    fromList (a:l) = Cons a $ fromList l 

そして

*List> listHead [1,2] 
1 
関連する問題