質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.02%
Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

Q&A

受付中

haskellでテキストファイルを読み込んで数字に変換したい

退会済みユーザー

退会済みユーザー

総合スコア0

Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

1回答

0グッド

0クリップ

207閲覧

投稿2021/07/05 00:56

text

1aaaaabaa 2aaaabaaa 3aaabaaaa

上記のテキストファイルを読み込んで
[[1,1,1,1,1,2,1,1],[1,1,1,1,2,1,1,1],[1,1,1,2,1,1,1,1]]
という連結リストに変換したいと考えて下記のコードを書きました。
しかしsplit :: [a]->[[Int],[Int]]でエラーを吐かれます。
どうしたら実装出来ますか。教えてください。

haskell

1import System.IO 2--1行ずつに連結リスト化 3split :: [a]->[[Int],[Int]] 4split []=[] 5split (x:xs) = (separate x,split xs) 6--,でわける 7separate:: [a]->[Int] 8separate[]=[] 9separate (x:xs)=[change_number x,separate xs] 10--数字に変換 11change_number:: a->Int 12change_number x 13 |x=="a"=1 14 |x=="b"=2 15 16main :: IO() 17main = do 18 handle <- openFile "sample.txt" ReadMode 19 text <- hGetContents handle 20 let ls = lines text --1行ずつ書き出し 21 print split ls--多重連結リスト化 22 hClose handle

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

tamoto

2021/07/05 07:29

ぱっと見、ツッコミどころが多すぎて回答しきれないです。 Haskell はなんとなくで書いて動くものではないので、まずは文法の学習をするべきかと思います。 添削依頼は NG なので、まずは「自分で考えて書いた部分」が文法的に間違っていないか一つずつ確認してみるのが良いです。 ひとまず文法を正せば、それからはコンパイラがエラー内容を教えてくれるようになります。
kakkun61

2021/07/05 16:10

インターネット上の記事ではなく一度ちゃんとレビューのされてまとまった商業誌を通読することをおすすめします。

回答1

1

tomato さんのコメントや私の前回の回答にも書きましたが、「類推で書く」ことをやめて文法をちゃんと調べて書くようにするのが近道です。

haskell

1import System.IO 2 3-- 1行ずつに連結リスト化 4split :: [a] -> [[Int], [Int]] -- (1) 5split [] = [] 6split (x:xs) = (separate x, split xs) 7 8-- ,でわける 9separate :: [a] -> [Int] -- (2) 10separate [] = [] 11separate (x:xs) = [change_number x, separate xs] 12 13-- 数字に変換 14change_number :: a->Int 15change_number x 16 | x == "a" = 1 17 | x == "b" = 2 18 19main :: IO () 20main = do 21 handle <- openFile "sample.txt" ReadMode 22 text <- hGetContents handle 23 let ls = lines text --1行ずつ書き出し 24 print split ls--多重連結リスト化 -- (3) 25 hClose handle
  1. [[Int], [Int]] というような型は存在しません。また前回の回答にも書きましたが、1行ずつにリストに分ける関数は lines ですので split は実装する必要がありません。lines に相当するものを自分で実装しているのかと思いましたが main 内で lines を使用しているため、そのような目的ではないと判断しました。
  2. これは文字列をカンマで分ける関数を書きたいと認識しました。まず型を考えると、「文字列を受け取って、文字列のリストを返す関数」となるはずです。これをコードに変換すると String -> [String] となります。次に実装についてですが、カンマで分割する関数なのにどこにも ',' を使用していないのは何かがおかしいと気付いてほしいです。また「カンマで分ける」という動作の中に「数字に変換」は含まれていないはずなので separate 関数で change_number 関数を使用していることも何かおかしいと思うようにしてください。あれ、そもそも入力するテキストファイルにカンマがないのでこの関数は要らないように思うのですが?
  3. これでは print 関数が2引数のように扱ってしまっています。

参考になるか分かりませんが、期待する動作のコードを掲載しておきます(Wandbox で実行)。

haskell

1import System.IO 2 3-- 数字に変換 4replaceToNumber :: Char -> Int 5replaceToNumber 'a' = 1 6replaceToNumber _ = 2 7 8main :: IO () 9main = do 10 text <- hGetContents stdin 11 print $ (replaceToNumber <$>) <$> lines text

投稿2021/07/05 16:09

kakkun61

総合スコア285

igrep👍を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.02%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。