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

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

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

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

Q&A

1回答

1500閲覧

haskellでテキストファイルを読み込んで1行ずつ配列に入れたい

退会済みユーザー

退会済みユーザー

総合スコア0

Haskell

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

0グッド

0クリップ

投稿2021/07/04 09:51

https://www.nslabs.jp/haskell-fileio.rhtml
上記のサイトの「テキストファイルを1行ずつ表示する関数」を「1行ずつ読み込んで多重配列にいれる」という関数に改造したいと考えて下記のコードを書きました
しかしsplitEvery 1 strで
textsample.hs:35:9: error: parse error on input ‘splitEvery’
|
35 | splitEvery 1 str[]--1文字ずつ分割
というエラーが吐かれます
どうしたら動きますか。教えてください

haskell

1text_get_array :: Handle->[a] 2text_get_array fp 3 |hIsEOF fp ==true =[] 4 |otherwise= 5 let str[] = DTI.hGetLine fp --1行読み込み 6 splitEvery 1 str--1文字ずつ分割 7 str ++ get_and_print fp

"qwertuiop"
"asdfgjkl"
"zxcvbnm"
とサンプルでは出力されるので
[[q,w,e,r,t,u,i,o,p],[a,s,d,f,g,j,k,l],[z,x,c,v,b,n,m]]
という配列を取得したい

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

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

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

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

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

guest

回答1

0

回答を2つの部分に分けます。1つめは「1行ずつ読み込んで多重配列にいれる」を解決する部分、2つめは掲載のコードの問題点を指摘する部分です。


まず1つめの「1行ずつ読み込んで多重配列にいれる」を実装すると下記のようになります(Wandbox で実行)。

haskell

1main :: IO () 2main = do 3 c <- getContents 4 let ls = lines c 5 print ls

解説です。

初めに Haskell では配列はほとんど使われません(少なくとも初心者のうちは)。代わりに連結リストを使います。
標準入力を [[Char] の型の値で得るのが getContents です(ドキュメント)。
[Char] は標準で String という別名がついています(ドキュメント)。
getContents の型は IO [String] つまり IO [[Char]] です。
IO a という型の値から a という型の値を取り出すには do 構文の <- という構文を使います。
ですので上記コードでは c[String] という型になります。
次に lines 関数を使います。
これは String -> [String] という型で、引数の文字列を CR や LF で分割し、文字列のリストとして返します(ドキュメント)。
こうすると ls の型は [String] つまり [[Char]] となります。
これを print で出力します。


次に掲載コードの問題点です。

haskell

1text_get_array :: Handle->[a] -- (1) 2text_get_array fp 3 |hIsEOF fp ==true =[] -- (2) 4 |otherwise= 5 let str[] = DTI.hGetLine fp --1行読み込み -- (3) 6 splitEvery 1 str--1文字ずつ分割 -- (4) 7 str ++ get_and_print fp -- (5)
  1. この関数は内部に IO の操作をするため返り値の型は必ず IO a という形になります。
  2. hIsEOFHandle -> IO Bool という型の関数なので、Bool の値を得るためには do<- の構文を使う必要があります(ドキュメント)。
  3. hIsEOF と同じく Data.Text.IO.hGetLineHandle -> IO Text という型なので do<- の構文を使います。また、変数名の後に [] を書く構文はありません。
  4. Haskell では変数を再束縛できないため操作した結果を取得するためには返り値が必要です(純粋な関数の場合)。ここでは返り値がないため操作の結果を捨てていることになります。
  5. ここも同様に get_and_printIO a のような型の値を返すので do<- が必要です。

str[] のような書き方を見るに C 系の文法の推測でコードを書いていらっしゃるようですが、Haskell はそのような系統とは文法が異なります。推測ではなかなか書けませんので一度 C 系は忘れてしまうのが得策です。

投稿2021/07/04 14:28

kakkun61

総合スコア285

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

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

退会済みユーザー

退会済みユーザー

2021/07/05 00:49

ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問