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

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

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

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

Q&A

1回答

417閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

Haskell

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

0グッド

0クリップ

投稿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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tamoto

2021/07/05 07:29

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

2021/07/05 16:10

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

回答1

0

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問